home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Languguage OS 2
/
Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO
/
gnu
/
xshogi11.lha
/
xshogi-1.1
/
xshogi.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-04-28
|
144KB
|
5,296 lines
#define XBOARD_VERSION "2.0"
#include <stdio.h>
#include <ctype.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <time.h>
#ifdef HAS_GETTIMEOFDAY
#ifndef ESIX
#include <sys/time.h>
#endif
#endif
#ifdef __STDC__
#ifndef ESIX
#ifndef apollo
#include <stdlib.h>
#endif
#endif
#endif
#if SYSTEM_FIVE || SYSV
#include <sys/types.h>
#include <sys/stat.h>
#ifdef AIXV3
#include <fcntl.h>
#else
#include <sys/fcntl.h>
#endif AIXV3
#if SVR4
#include <stropts.h>
#endif
#endif
#if defined(__STDC__) || SYSTEM_FIVE || SYSV
#include <string.h>
#else
#include <strings.h>
#endif
#include <pwd.h>
#ifdef IRIS
#include <sys/sysmacros.h>
#endif
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Shell.h>
#include <X11/Xaw/Dialog.h>
#include <X11/Xaw/Form.h>
#include <X11/Xaw/List.h>
#include <X11/Xaw/Label.h>
#include <X11/Xaw/SimpleMenu.h>
#include <X11/Xaw/SmeBSB.h>
#include <X11/Xaw/SmeLine.h>
#include <X11/cursorfont.h>
#include "version.h"
#include "xshogi.h"
#include "eastern_bitmaps/icon.xbm"
#include "eastern_bitmaps/bigsolid.xbm"
#include "eastern_bitmaps/smallsolid.xbm"
#include "eastern_bitmaps/bigsolidR.xbm"
#include "eastern_bitmaps/smallsolidR.xbm"
#ifdef WESTERN_BITMAPS
#include "western_bitmaps/none.xbm"
#include "western_bitmaps/king.xbm"
#include "western_bitmaps/rook.xbm"
#include "western_bitmaps/rookP.xbm"
#include "western_bitmaps/bishop.xbm"
#include "western_bitmaps/bishopP.xbm"
#include "western_bitmaps/gold.xbm"
#include "western_bitmaps/silver.xbm"
#include "western_bitmaps/silverP.xbm"
#include "western_bitmaps/knight.xbm"
#include "western_bitmaps/knightP.xbm"
#include "western_bitmaps/lance.xbm"
#include "western_bitmaps/lanceP.xbm"
#include "western_bitmaps/pawn.xbm"
#include "western_bitmaps/pawnP.xbm"
#include "western_bitmaps/kingR.xbm"
#include "western_bitmaps/rookR.xbm"
#include "western_bitmaps/rookPR.xbm"
#include "western_bitmaps/bishopR.xbm"
#include "western_bitmaps/bishopPR.xbm"
#include "western_bitmaps/goldR.xbm"
#include "western_bitmaps/silverR.xbm"
#include "western_bitmaps/silverPR.xbm"
#include "western_bitmaps/knightR.xbm"
#include "western_bitmaps/knightPR.xbm"
#include "western_bitmaps/lanceR.xbm"
#include "western_bitmaps/lancePR.xbm"
#include "western_bitmaps/pawnR.xbm"
#include "western_bitmaps/pawnPR.xbm"
#else
#include "eastern_bitmaps/none.xbm"
#include "eastern_bitmaps/king.xbm"
#include "eastern_bitmaps/rook.xbm"
#include "eastern_bitmaps/rookP.xbm"
#include "eastern_bitmaps/bishop.xbm"
#include "eastern_bitmaps/bishopP.xbm"
#include "eastern_bitmaps/gold.xbm"
#include "eastern_bitmaps/silver.xbm"
#include "eastern_bitmaps/silverP.xbm"
#include "eastern_bitmaps/knight.xbm"
#include "eastern_bitmaps/knightP.xbm"
#include "eastern_bitmaps/lance.xbm"
#include "eastern_bitmaps/lanceP.xbm"
#include "eastern_bitmaps/pawn.xbm"
#include "eastern_bitmaps/pawnP.xbm"
#include "eastern_bitmaps/kingR.xbm"
#include "eastern_bitmaps/rookR.xbm"
#include "eastern_bitmaps/rookPR.xbm"
#include "eastern_bitmaps/bishopR.xbm"
#include "eastern_bitmaps/bishopPR.xbm"
#include "eastern_bitmaps/goldR.xbm"
#include "eastern_bitmaps/silverR.xbm"
#include "eastern_bitmaps/silverPR.xbm"
#include "eastern_bitmaps/knightR.xbm"
#include "eastern_bitmaps/knightPR.xbm"
#include "eastern_bitmaps/lanceR.xbm"
#include "eastern_bitmaps/lancePR.xbm"
#include "eastern_bitmaps/pawnR.xbm"
#include "eastern_bitmaps/pawnPR.xbm"
#include "eastern_bitmaps/none_m.xbm"
#include "eastern_bitmaps/bigsolid_m.xbm"
#include "eastern_bitmaps/smallsolid_m.xbm"
#include "eastern_bitmaps/bigsolidR_m.xbm"
#include "eastern_bitmaps/smallsolidR_m.xbm"
#include "eastern_bitmaps/king_m.xbm"
#include "eastern_bitmaps/rook_m.xbm"
#include "eastern_bitmaps/rookP_m.xbm"
#include "eastern_bitmaps/bishop_m.xbm"
#include "eastern_bitmaps/bishopP_m.xbm"
#include "eastern_bitmaps/gold_m.xbm"
#include "eastern_bitmaps/silver_m.xbm"
#include "eastern_bitmaps/silverP_m.xbm"
#include "eastern_bitmaps/knight_m.xbm"
#include "eastern_bitmaps/knightP_m.xbm"
#include "eastern_bitmaps/lance_m.xbm"
#include "eastern_bitmaps/lanceP_m.xbm"
#include "eastern_bitmaps/pawn_m.xbm"
#include "eastern_bitmaps/pawnP_m.xbm"
#include "eastern_bitmaps/kingR_m.xbm"
#include "eastern_bitmaps/rookR_m.xbm"
#include "eastern_bitmaps/rookPR_m.xbm"
#include "eastern_bitmaps/bishopR_m.xbm"
#include "eastern_bitmaps/bishopPR_m.xbm"
#include "eastern_bitmaps/goldR_m.xbm"
#include "eastern_bitmaps/silverR_m.xbm"
#include "eastern_bitmaps/silverPR_m.xbm"
#include "eastern_bitmaps/knightR_m.xbm"
#include "eastern_bitmaps/knightPR_m.xbm"
#include "eastern_bitmaps/lanceR_m.xbm"
#include "eastern_bitmaps/lancePR_m.xbm"
#include "eastern_bitmaps/pawnR_m.xbm"
#include "eastern_bitmaps/pawnPR_m.xbm"
#include "eastern_bitmaps/none_l.xbm"
#include "eastern_bitmaps/bigsolid_l.xbm"
#include "eastern_bitmaps/smallsolid_l.xbm"
#include "eastern_bitmaps/bigsolidR_l.xbm"
#include "eastern_bitmaps/smallsolidR_l.xbm"
#include "eastern_bitmaps/king_l.xbm"
#include "eastern_bitmaps/rook_l.xbm"
#include "eastern_bitmaps/rookP_l.xbm"
#include "eastern_bitmaps/bishop_l.xbm"
#include "eastern_bitmaps/bishopP_l.xbm"
#include "eastern_bitmaps/gold_l.xbm"
#include "eastern_bitmaps/silver_l.xbm"
#include "eastern_bitmaps/silverP_l.xbm"
#include "eastern_bitmaps/knight_l.xbm"
#include "eastern_bitmaps/knightP_l.xbm"
#include "eastern_bitmaps/lance_l.xbm"
#include "eastern_bitmaps/lanceP_l.xbm"
#include "eastern_bitmaps/pawn_l.xbm"
#include "eastern_bitmaps/pawnP_l.xbm"
#include "eastern_bitmaps/kingR_l.xbm"
#include "eastern_bitmaps/rookR_l.xbm"
#include "eastern_bitmaps/rookPR_l.xbm"
#include "eastern_bitmaps/bishopR_l.xbm"
#include "eastern_bitmaps/bishopPR_l.xbm"
#include "eastern_bitmaps/goldR_l.xbm"
#include "eastern_bitmaps/silverR_l.xbm"
#include "eastern_bitmaps/silverPR_l.xbm"
#include "eastern_bitmaps/knightR_l.xbm"
#include "eastern_bitmaps/knightPR_l.xbm"
#include "eastern_bitmaps/lanceR_l.xbm"
#include "eastern_bitmaps/lancePR_l.xbm"
#include "eastern_bitmaps/pawnR_l.xbm"
#include "eastern_bitmaps/pawnPR_l.xbm"
#endif
void main P((int argc, char **argv));
void CreateGCs P((void));
void CreatePieces P((void));
void CreatePieceMenus P((void));
void PieceMenuPopup P((Widget w, XEvent *event, String *params,
Cardinal *num_params));
static void PieceMenuSelect P((Widget w, ChessSquare piece, caddr_t junk));
static void SetBlackToPlay P((void));
static void SetWhiteToPlay P((void));
void ReadBitmap P((String name, Pixmap *pm, Pixmap *qm,
char small_bits[], char medium_bits[], char large_bits[]));
void CreateGrid P((void));
int EventToSquare P((int x));
int EventToXSquare P((int x));
ChessSquare CharToPiece P((int c, int p));
void DrawSquare P((int row, int column, ChessSquare piece));
void BlinkSquare P((int row, int column, ChessSquare piece));
void EventProc P((Widget widget, caddr_t unused, XEvent *event));
void DrawPosition P((Widget w, XExposeEvent *event));
void InitPosition P((void));
void CopyBoard P((Board to, Board from));
void CopyCatches P((Catched to, Catched from));
void ClearCatches P((Catched to));
void UpdateCatched P((int c, int f, int d, int a, int cm));
void SendCurrentBoard P((FILE *fp));
void SendBoard P((FILE *fp, Board board, Catched catches));
void HandleUserMove P((Widget w, XEvent *event));
void FinishUserMove P((ChessMove move_type, int to_x, int to_y));
void HandleMachineMove P((char *message, FILE *fp));
void ReadGameFile P((void));
int ReadGameFileProc P((void));
void MakeMove P((ChessMove *move_type, int from_x, int from_y,
int to_x, int to_y));
void InitChessProgram P((char *host_name, char *program_name, int *pid,
FILE **to, FILE **from, XtIntervalId *xid));
void ShutdownChessPrograms P((char *message));
void CommentPopUp P((char *label));
void FileNamePopUp P((char *label, void (*proc)(char *name)));
void FileNameCallback P((Widget w, XtPointer client_data,
XtPointer call_data));
void FileNameAction P((Widget w, XEvent *event));
void PromotionPopUp P((ChessSquare piece, int to_x, int to_y));
void PromotionCallback P((Widget w, XtPointer client_data,
XtPointer call_data));
void FileModePopUp P((char *name));
void FileModeCallback P((Widget w, XtPointer client_data,
XtPointer call_data));
void SelectCommand P((Widget w, XtPointer client_data, XtPointer call_data));
void ModeHighlight P((void));
void GameProc P((void));
void QuitProc P((void));
int PlayFromGameFileProc P((char *name));
void MachinePlaysWhiteProc P((void));
void ForwardProc P((void));
void ResetFileProc P((void));
void ResetProc P((void));
int SetupPositionFromFileProc P((char *name));
void MachinePlaysBlackProc P((void));
void BackwardProc P((void));
void FlipProc P((void));
void SaveGameProc P((char *name));
void SwitchProc P((void));
void EditPositionProc P((void));
void EditPositionDone P((void));
void ForceProc P((void));
void HintProc P((void));
void SavePositionProc P((char *name));
void TwoMachinesPlayProc P((void));
void PauseProc P((void));
void Iconify P((void));
void SendToProgram P((char *message, FILE *fp));
void ReceiveFromProgram P((FILE *fp, int *source, XtInputId *id));
void SendSearchDepth P((FILE *fp));
void DisplayMessage P((char *message));
void DisplayName P((char *name));
void Attention P((int pid));
void DisplayClocks P((int clock_mode));
void DisplayTimerLabel P((Widget w, char *color, long timer));
char *TimeString P((long tm));
void Usage P((void));
char *StrStr P((char *string, char *match));
int StrCaseCmp P((char *s1, char *s2));
int ToLower P((int c));
int ToUpper P((int c));
#if SYSTEM_FIVE || SYSV
char *PseudoTTY P((int *ptyv));
#else
void CatchPipeSignal P((int dummy));
#endif
#define off_board(x) (x < 2 || x > BOARD_SIZE+1)
extern void parseGameFile P((void));
/*
* XShogi depends on Xt R4 or higher
*/
int xtVersion = XtSpecificationRelease;
int xScreen;
Display *xDisplay;
Window xBoardWindow;
GC lightSquareGC, darkSquareGC, lineGC, wdPieceGC, wlPieceGC,
bdPieceGC, blPieceGC, wbPieceGC, bwPieceGC, coordGC,
charPieceGC, dropPiece;
Pixmap reversePawnBitmap, reverseLanceBitmap, reverseKnightBitmap, reverseSilverBitmap,
reverseGoldBitmap, reverseBishopBitmap, reverseRookBitmap,
reversePPawnBitmap, reversePLanceBitmap, reversePKnightBitmap,
reversePSilverBitmap, reversePBishopBitmap, reversePRookBitmap,
reverseKingBitmap,
reverseBigSolidBitmap, reverseSmallSolidBitmap,
normalBigSolidBitmap, normalSmallSolidBitmap,
normalPawnBitmap, normalLanceBitmap, normalKnightBitmap,
normalSilverBitmap, normalGoldBitmap,
normalBishopBitmap, normalRookBitmap,
normalPPawnBitmap, normalPLanceBitmap, normalPKnightBitmap,
normalPSilverBitmap, normalPBishopBitmap, normalPRookBitmap,
normalKingBitmap, iconPixmap;
Widget shellWidget, formWidget, boardWidget, commandsWidget, messageWidget,
blackTimerWidget, whiteTimerWidget, nameWidget, widgetList[6],
commentShell, promotionShell, blackPieceMenu, whitePieceMenu,
filemodeShell;
XSegment gridSegments[(BOARD_SIZE + 1) * 2];
XtIntervalId firstProgramXID = 0, secondProgramXID = 0,
readGameXID = 0, timerXID = 0, blinkSquareXID = 0;
XFontStruct *labelFont, *coordFont;
XtAppContext appContext;
void (*fileProc) P((char *name));
FILE *fromFirstProgFP, *toFirstProgFP, *fromSecondProgFP,
*toSecondProgFP, *gameFileFP, *lastMsgFP;
int currentMove = 0, forwardMostMove = 0, firstProgramPID = 0,
secondProgramPID = 0, squareSize = SMALL_SQUARE_SIZE, fromX = -1,
fromY = -1, firstMove = True, flipView = False,
xshogiDebug = True, commentUp = False, filenameUp = False,
whitePlaysFirst = False, startedFromSetupPosition = False,
promotionUp = False, searchTime = 0, pmFromX = -1, pmFromY = -1,
blackFlag = False, whiteFlag = False, maybeThinking = False,
filemodeUp = False;
Pixel timerForegroundPixel, timerBackgroundPixel;
MatchMode matchMode = MatchFalse;
GameMode gameMode = BeginningOfGame, lastGameMode = BeginningOfGame;
BoardSize boardSize = Small;
char moveList[MAX_MOVES][MOVE_LEN], parseList[MAX_MOVES][MOVE_LEN * 2],
ptyname[24], *chessDir, *programName;
long blackTimeRemaining, whiteTimeRemaining, timeControl;
extern char currentMoveString[];
int black_pixel_is_zero;
Catched catches[MAX_MOVES];
#define pawn 0
#define lance 1
#define knight 2
#define silver 3
#define gold 4
#define bishop 5
#define rook 6
#define king 7
#define no_piece 8
char catchedIndexToChar[8] = {
'P', 'L', 'N', 'S', 'G', 'B', 'R', 'K'
};
ChessSquare catchedIndexToPiece[2][8] = {
BlackPawn, BlackLance, BlackKnight, BlackSilver, BlackGold,
BlackBishop, BlackRook, BlackKing,
WhitePawn, WhiteLance, WhiteKnight, WhiteSilver, WhiteGold,
WhiteBishop, WhiteRook, WhiteKing
};
pieceToCatchedIndex[] = {
pawn, lance, knight, silver, gold, bishop, rook,
pawn, lance, knight, silver, bishop, rook, king,
pawn, lance, knight, silver, gold, bishop, rook,
pawn, lance, knight, silver, bishop, rook, king,
no_piece
};
Board boards[MAX_MOVES], initialPosition = {
{ BlackLance, BlackKnight, BlackSilver, BlackGold, BlackKing,
BlackGold, BlackSilver, BlackKnight, BlackLance },
{ EmptySquare, BlackBishop, EmptySquare, EmptySquare, EmptySquare,
EmptySquare, EmptySquare, BlackRook, EmptySquare },
{ BlackPawn, BlackPawn, BlackPawn, BlackPawn, BlackPawn,
BlackPawn, BlackPawn, BlackPawn, BlackPawn },
{ EmptySquare, EmptySquare, EmptySquare, EmptySquare, EmptySquare,
EmptySquare, EmptySquare, EmptySquare, EmptySquare } ,
{ EmptySquare, EmptySquare, EmptySquare, EmptySquare, EmptySquare,
EmptySquare, EmptySquare, EmptySquare, EmptySquare } ,
{ EmptySquare, EmptySquare, EmptySquare, EmptySquare, EmptySquare,
EmptySquare, EmptySquare, EmptySquare, EmptySquare } ,
{ WhitePawn, WhitePawn, WhitePawn, WhitePawn, WhitePawn,
WhitePawn, WhitePawn, WhitePawn, WhitePawn },
{ EmptySquare, WhiteRook, EmptySquare, EmptySquare, EmptySquare,
EmptySquare, EmptySquare, WhiteBishop, EmptySquare },
{ WhiteLance, WhiteKnight, WhiteSilver, WhiteGold, WhiteKing,
WhiteGold, WhiteSilver, WhiteKnight, WhiteLance }
};
String buttonStrings[] = {
"Quit", "Load Game", "Machine White", "Forward",
"Reset", "Load Position", "Machine Black", "Backward",
"Flip View", "Save Game", "Force Moves", "Pause",
"Hint", "Save Position", "Two Machines", "Edit Position"
};
/* must be in same order as buttonStrings! */
typedef enum {
ButtonQuit, ButtonLoadGame, ButtonMachineWhite, ButtonForward,
ButtonReset, ButtonLoadPosition, ButtonMachineBlack, ButtonBackward,
ButtonFlipView, ButtonSaveGame, ButtonForceMoves, ButtonPause,
ButtonHint, ButtonSavePosition, ButtonTwoMachines, ButtonEditPosition
} Button;
#define PIECE_MENU_SIZE 18
String pieceMenuStrings[PIECE_MENU_SIZE] = {
"----", "Pawn", "Lance", "Knight", "Silver",
"Gold", "Bishop", "Rook",
"PPawn", "PLance", "PKnight", "PSilver",
"PBishop", "PRook", "King",
"----", "Empty square", "Clear board"
};
/* must be in same order as PieceMenuStrings! */
ChessSquare pieceMenuTranslation[2][PIECE_MENU_SIZE] = {
{ (ChessSquare) 0, BlackPawn, BlackLance, BlackKnight, BlackSilver,
BlackGold, BlackBishop, BlackRook,
BlackPPawn, BlackPLance, BlackPKnight, BlackPSilver,
BlackPBishop, BlackPRook, BlackKing,
(ChessSquare) 0, EmptySquare, ClearBoard },
{ (ChessSquare) 0, WhitePawn, WhiteLance, WhiteKnight, WhiteSilver,
WhiteGold, WhiteBishop, WhiteRook,
WhitePPawn, WhitePLance, WhitePKnight, WhitePSilver,
WhitePBishop, WhitePRook, WhiteKing,
(ChessSquare) 0, EmptySquare, ClearBoard },
};
Arg shellArgs[] = {
{ XtNwidth, 0 },
{ XtNheight, 0 },
{ XtNminWidth, 0 },
{ XtNminHeight, 0 },
{ XtNmaxWidth, 0 },
{ XtNmaxHeight, 0 }
};
Arg boardArgs[] = {
{ XtNborderWidth, 0 },
{ XtNwidth, LINE_GAP + (BOARD_SIZE+4) * (SMALL_SQUARE_SIZE + LINE_GAP) },
{ XtNheight, LINE_GAP + BOARD_SIZE * (SMALL_SQUARE_SIZE + LINE_GAP) }
};
Arg commandsArgs[] = {
{ XtNborderWidth, 0 },
{ XtNdefaultColumns, 4 },
{ XtNforceColumns, True },
{ XtNlist, (XtArgVal) buttonStrings },
{ XtNnumberStrings, XtNumber(buttonStrings) }
};
Arg messageArgs[] = {
{ XtNborderWidth, 0 },
{ XtNjustify, (XtArgVal) XtJustifyLeft },
{ XtNlabel, (XtArgVal) "starting..." }
};
Arg timerArgs[] = {
{ XtNborderWidth, 0 },
{ XtNjustify, (XtArgVal) XtJustifyLeft }
};
Arg nameArgs[] = {
{ XtNborderWidth, 0 },
{ XtNjustify, (XtArgVal) XtJustifyLeft }
};
typedef struct {
Pixel blackPieceColor;
Pixel whitePieceColor;
Pixel lightSquareColor;
Pixel darkSquareColor;
int movesPerSession;
String initString;
String blackString;
String whiteString;
String firstChessProgram;
String secondChessProgram;
Boolean noChessProgram;
String firstHost;
String secondHost;
String reverseBigSolidBitmap;
String reverseSmallSolidBitmap;
String normalBigSolidBitmap;
String normalSmallSolidBitmap;
String reversePawnBitmap;
String reverseLanceBitmap;
String reverseKnightBitmap;
String reverseSilverBitmap;
String reverseGoldBitmap;
String reverseRookBitmap;
String reverseBishopBitmap;
String reversePPawnBitmap;
String reversePLanceBitmap;
String reversePKnightBitmap;
String reversePSilverBitmap;
String reversePBishopBitmap;
String reversePRookBitmap;
String reverseKingBitmap;
String normalPawnBitmap;
String normalLanceBitmap;
String normalKnightBitmap;
String normalSilverBitmap;
String normalGoldBitmap;
String normalRookBitmap;
String normalBishopBitmap;
String normalPPawnBitmap;
String normalPLanceBitmap;
String normalPKnightBitmap;
String normalPSilverBitmap;
String normalPBishopBitmap;
String normalPRookBitmap;
String normalKingBitmap;
String remoteShell;
float timeDelay;
String timeControl;
String loadGameFile;
String loadPositionFile;
String saveGameFile;
String savePositionFile;
String matchMode;
Boolean monoMode;
Boolean debugMode;
Boolean clockMode;
String boardSize;
Boolean Iconic;
String searchTime;
int searchDepth;
Boolean showCoords;
String coordFont;
} AppData, *AppDataPtr;
AppData appData;
XtResource clientResources[] = {
{
"blackPieceColor", "BlackPieceColor", XtRPixel, sizeof(Pixel),
XtOffset(AppDataPtr, blackPieceColor), XtRString,
BLACK_PIECE_COLOR
}, {
"whitePieceColor", "WhitePieceColor", XtRPixel, sizeof(Pixel),
XtOffset(AppDataPtr, whitePieceColor), XtRString,
WHITE_PIECE_COLOR
}, {
"lightSquareColor", "LightSquareColor", XtRPixel,
sizeof(Pixel), XtOffset(AppDataPtr, lightSquareColor),
XtRString, LIGHT_SQUARE_COLOR
}, {
"darkSquareColor", "DarkSquareColor", XtRPixel, sizeof(Pixel),
XtOffset(AppDataPtr, darkSquareColor), XtRString,
DARK_SQUARE_COLOR
}, {
"movesPerSession", "movesPerSession", XtRInt, sizeof(int),
XtOffset(AppDataPtr, movesPerSession), XtRImmediate,
(XtPointer) MOVES_PER_SESSION
}, {
"initString", "initString", XtRString, sizeof(String),
XtOffset(AppDataPtr, initString), XtRString, INIT_STRING
}, {
"blackString", "blackString", XtRString, sizeof(String),
XtOffset(AppDataPtr, blackString), XtRString, BLACK_STRING
}, {
"whiteString", "whiteString", XtRString, sizeof(String),
XtOffset(AppDataPtr, whiteString), XtRString, WHITE_STRING
}, {
"firstChessProgram", "firstChessProgram", XtRString,
sizeof(String), XtOffset(AppDataPtr, firstChessProgram),
XtRString, FIRST_CHESS_PROGRAM
}, {
"secondChessProgram", "secondChessProgram", XtRString,
sizeof(String), XtOffset(AppDataPtr, secondChessProgram),
XtRString, SECOND_CHESS_PROGRAM
}, {
"noChessProgram", "noChessProgram", XtRBoolean,
sizeof(Boolean), XtOffset(AppDataPtr, noChessProgram),
XtRImmediate, (XtPointer) False
}, {
"firstHost", "firstHost", XtRString, sizeof(String),
XtOffset(AppDataPtr, firstHost), XtRString, FIRST_HOST
}, {
"secondHost", "secondHost", XtRString, sizeof(String),
XtOffset(AppDataPtr, secondHost), XtRString, SECOND_HOST
}, {
"reversePawnBitmap", "reversePawnBitmap", XtRString,
sizeof(String), XtOffset(AppDataPtr, reversePawnBitmap),
XtRString, NULL
}, {
"reverseLanceBitmap", "reverseLanceBitmap", XtRString,
sizeof(String), XtOffset(AppDataPtr, reverseLanceBitmap),
XtRString, NULL
}, {
"reverseKnightBitmap", "reverseKnightBitmap", XtRString,
sizeof(String), XtOffset(AppDataPtr, reverseKnightBitmap),
XtRString, NULL
}, {
"reverseSilverBitmap", "reverseSilverBitmap", XtRString,
sizeof(String), XtOffset(AppDataPtr, reverseSilverBitmap),
XtRString, NULL
}, {
"reverseGoldBitmap", "reverseGoldBitmap", XtRString,
sizeof(String), XtOffset(AppDataPtr, reverseGoldBitmap),
XtRString, NULL
}, {
"reverseRookBitmap", "reverseRookBitmap", XtRString,
sizeof(String), XtOffset(AppDataPtr, reverseRookBitmap),
XtRString, NULL
}, {
"reverseBishopBitmap", "reverseBishopBitmap", XtRString,
sizeof(String), XtOffset(AppDataPtr, reverseBishopBitmap),
XtRString, NULL
}, {
"reversePPawnBitmap", "reversePPawnBitmap", XtRString,
sizeof(String), XtOffset(AppDataPtr, reversePPawnBitmap),
XtRString, NULL
}, {
"reversePLanceBitmap", "reversePLanceBitmap", XtRString,
sizeof(String), XtOffset(AppDataPtr, reversePLanceBitmap),
XtRString, NULL
}, {
"reversePKnightBitmap", "reversePKnightBitmap", XtRString,
sizeof(String), XtOffset(AppDataPtr, reversePKnightBitmap),
XtRString, NULL
}, {
"reversePSilverBitmap", "reversePSilverBitmap", XtRString,
sizeof(String), XtOffset(AppDataPtr, reversePSilverBitmap),
XtRString, NULL
}, {
"reversePRookBitmap", "reversePRookBitmap", XtRString,
sizeof(String), XtOffset(AppDataPtr, reversePRookBitmap),
XtRString, NULL
}, {
"reversePBishopBitmap", "reversePBishopBitmap", XtRString,
sizeof(String), XtOffset(AppDataPtr, reversePBishopBitmap),
XtRString, NULL
}, {
"reverseKingBitmap", "reverseKingBitmap", XtRString,
sizeof(String), XtOffset(AppDataPtr, reverseKingBitmap),
XtRString, NULL
}, {
"normalPawnBitmap", "normalPawnBitmap", XtRString,
sizeof(String), XtOffset(AppDataPtr, normalPawnBitmap),
XtRString, NULL
}, {
"normalLanceBitmap", "normalLanceBitmap", XtRString,
sizeof(String), XtOffset(AppDataPtr, normalLanceBitmap),
XtRString, NULL
}, {
"normalKnightBitmap", "normalKnightBitmap", XtRString,
sizeof(String), XtOffset(AppDataPtr, normalKnightBitmap),
XtRString, NULL
}, {
"normalSilverBitmap", "normalSilverBitmap", XtRString,
sizeof(String), XtOffset(AppDataPtr, normalSilverBitmap),
XtRString, NULL
}, {
"normalGoldBitmap", "normalGoldBitmap", XtRString,
sizeof(String), XtOffset(AppDataPtr, normalGoldBitmap),
XtRString, NULL
}, {
"normalBishopBitmap", "normalBishopBitmap", XtRString,
sizeof(String), XtOffset(AppDataPtr, normalBishopBitmap),
XtRString, NULL
}, {
"normalRookBitmap", "normalRookBitmap", XtRString,
sizeof(String), XtOffset(AppDataPtr, normalRookBitmap),
XtRString, NULL
}, {
"normalPPawnBitmap", "normalPPawnBitmap", XtRString,
sizeof(String), XtOffset(AppDataPtr, normalPPawnBitmap),
XtRString, NULL
}, {
"normalPLanceBitmap", "normalPLanceBitmap", XtRString,
sizeof(String), XtOffset(AppDataPtr, normalPLanceBitmap),
XtRString, NULL
}, {
"normalPKnightBitmap", "normalPKnightBitmap", XtRString,
sizeof(String), XtOffset(AppDataPtr, normalPKnightBitmap),
XtRString, NULL
}, {
"normalPSilverBitmap", "normalPSilverBitmap", XtRString,
sizeof(String), XtOffset(AppDataPtr, normalPSilverBitmap),
XtRString, NULL
}, {
"normalPBishopBitmap", "normalPBishopBitmap", XtRString,
sizeof(String), XtOffset(AppDataPtr, normalPBishopBitmap),
XtRString, NULL
}, {
"normalPRookBitmap", "normalPRookBitmap", XtRString,
sizeof(String), XtOffset(AppDataPtr, normalPRookBitmap),
XtRString, NULL
}, {
"normalKingBitmap", "normalKingBitmap", XtRString,
sizeof(String), XtOffset(AppDataPtr, normalKingBitmap),
XtRString, NULL
}, {
"remoteShell", "remoteShell", XtRString, sizeof(String),
XtOffset(AppDataPtr, remoteShell), XtRString, "rsh"
}, {
"timeDelay", "timeDelay", XtRFloat, sizeof(float),
XtOffset(AppDataPtr, timeDelay), XtRString,
(XtPointer) TIME_DELAY
}, {
"timeControl", "timeControl", XtRString, sizeof(String),
XtOffset(AppDataPtr, timeControl), XtRString,
(XtPointer) TIME_CONTROL
}, {
"loadGameFile", "loadGameFile", XtRString, sizeof(String),
XtOffset(AppDataPtr, loadGameFile), XtRString, NULL
}, {
"loadPositionFile", "loadPositionFile", XtRString,
sizeof(String), XtOffset(AppDataPtr, loadPositionFile),
XtRString, NULL
}, {
"saveGameFile", "saveGameFile", XtRString, sizeof(String),
XtOffset(AppDataPtr, saveGameFile), XtRString, ""
}, {
"savePositionFile", "savePositionFile", XtRString,
sizeof(String), XtOffset(AppDataPtr, savePositionFile),
XtRString, ""
}, {
"matchMode", "matchMode", XtRString, sizeof(String),
XtOffset(AppDataPtr, matchMode), XtRString, MATCH_MODE
}, {
"monoMode", "monoMode", XtRBoolean, sizeof(Boolean),
XtOffset(AppDataPtr, monoMode), XtRImmediate,
(XtPointer) False
}, {
"debugMode", "debugMode", XtRBoolean, sizeof(Boolean),
XtOffset(AppDataPtr, debugMode), XtRImmediate,
(XtPointer) False
}, {
"Iconic", "Iconic", XtRBoolean, sizeof(Boolean),
XtOffset(AppDataPtr, Iconic), XtRImmediate,
(XtPointer) False
}, {
"clockMode", "clockMode", XtRBoolean, sizeof(Boolean),
XtOffset(AppDataPtr, clockMode), XtRImmediate,
(XtPointer) True
}, {
"boardSize", "boardSize", XtRString, sizeof(String),
XtOffset(AppDataPtr, boardSize), XtRString, DEFAULT_SIZE
}, {
"searchTime", "searchTime", XtRString, sizeof(String),
XtOffset(AppDataPtr, searchTime), XtRString,
(XtPointer) NULL
}, {
"searchDepth", "searchDepth", XtRInt, sizeof(int),
XtOffset(AppDataPtr, searchDepth), XtRImmediate,
(XtPointer) 0
}, {
"showCoords", "showCoords", XtRBoolean, sizeof(Boolean),
XtOffset(AppDataPtr, showCoords), XtRImmediate,
(XtPointer) False
}, {
"coordFont", "coordFont", XtRString, sizeof(String),
XtOffset(AppDataPtr, coordFont), XtRString, COORD_FONT
}
};
Pixmap *pieceToReverse[] = {
&reversePawnBitmap, &reverseLanceBitmap, &reverseKnightBitmap,
&reverseSilverBitmap, &reverseGoldBitmap, &reverseBishopBitmap,
&reverseRookBitmap, &reversePPawnBitmap, &reversePLanceBitmap,
&reversePKnightBitmap, &reversePSilverBitmap, &reversePBishopBitmap,
&reversePRookBitmap, &reverseKingBitmap,
&reversePawnBitmap, &reverseLanceBitmap, &reverseKnightBitmap,
&reverseSilverBitmap, &reverseGoldBitmap, &reverseBishopBitmap,
&reverseRookBitmap, &reversePPawnBitmap, &reversePLanceBitmap,
&reversePKnightBitmap, &reversePSilverBitmap, &reversePBishopBitmap,
&reversePRookBitmap, &reverseKingBitmap
};
Pixmap *pieceToNormal[] = {
&normalPawnBitmap, &normalLanceBitmap, &normalKnightBitmap,
&normalSilverBitmap, &normalGoldBitmap, &normalBishopBitmap,
&normalRookBitmap, &normalPPawnBitmap, &normalPLanceBitmap,
&normalPKnightBitmap, &normalPSilverBitmap, &normalPBishopBitmap,
&normalPRookBitmap, &normalKingBitmap,
&normalPawnBitmap, &normalLanceBitmap, &normalKnightBitmap,
&normalSilverBitmap, &normalGoldBitmap, &normalBishopBitmap,
&normalRookBitmap, &normalPPawnBitmap, &normalPLanceBitmap,
&normalPKnightBitmap, &normalPSilverBitmap, &normalPBishopBitmap,
&normalPRookBitmap, &normalKingBitmap
};
Pixmap *pieceToReverseSolid[] = {
&reverseSmallSolidBitmap, &reverseSmallSolidBitmap, &reverseSmallSolidBitmap,
&reverseBigSolidBitmap, &reverseBigSolidBitmap, &reverseBigSolidBitmap,
&reverseBigSolidBitmap, &reverseSmallSolidBitmap, &reverseSmallSolidBitmap,
&reverseSmallSolidBitmap, &reverseBigSolidBitmap, &reverseBigSolidBitmap,
&reverseBigSolidBitmap, &reverseBigSolidBitmap,
&reverseSmallSolidBitmap, &reverseSmallSolidBitmap, &reverseSmallSolidBitmap,
&reverseBigSolidBitmap, &reverseBigSolidBitmap, &reverseBigSolidBitmap,
&reverseBigSolidBitmap, &reverseSmallSolidBitmap, &reverseSmallSolidBitmap,
&reverseSmallSolidBitmap, &reverseBigSolidBitmap, &reverseBigSolidBitmap,
&reverseBigSolidBitmap, &reverseBigSolidBitmap,
};
Pixmap *pieceToNormalSolid[] = {
&normalSmallSolidBitmap, &normalSmallSolidBitmap, &normalSmallSolidBitmap,
&normalBigSolidBitmap, &normalBigSolidBitmap, &normalBigSolidBitmap,
&normalBigSolidBitmap, &normalSmallSolidBitmap, &normalSmallSolidBitmap,
&normalSmallSolidBitmap, &normalBigSolidBitmap, &normalBigSolidBitmap,
&normalBigSolidBitmap, &normalBigSolidBitmap,
&normalSmallSolidBitmap, &normalSmallSolidBitmap, &normalSmallSolidBitmap,
&normalBigSolidBitmap, &normalBigSolidBitmap, &normalBigSolidBitmap,
&normalBigSolidBitmap, &normalSmallSolidBitmap, &normalSmallSolidBitmap,
&normalSmallSolidBitmap, &normalBigSolidBitmap, &normalBigSolidBitmap,
&normalBigSolidBitmap, &normalBigSolidBitmap,
};
int pieceIsPromoted[] = {
False, False, False, False, False, False, False,
True, True, True, True, True, True, False,
False, False, False, False, False, False, False,
True, True, True, True, True, True, False,
False
};
int piecePromotable[] = {
True, True, True, True, False, True, True,
False, False, False, False, False, False, False,
True, True, True, True, False, True, True,
False, False, False, False, False, False, False,
False
};
char pieceToChar[] = {
'P', 'L', 'N', 'S', 'G', 'B', 'R', 'P', 'L', 'N', 'S', 'B', 'R', 'K',
'p', 'l', 'n', 's', 'g', 'b', 'r', 'p', 'l', 'n', 's', 'b', 'r', 'k',
'.'
};
#ifdef WESTERN_BITMAPS
int pieceisWhite[] = {
True, True, True, True, True, True, True,
True, True, True, True, True, True, True,
False, False, False, False, False, False, False,
False, False, False, False, False, False, False,
False
};
#endif
ChessSquare pieceToPromoted[] = {
BlackPPawn, BlackPLance, BlackPKnight, BlackPSilver, BlackGold,
BlackPBishop, BlackPRook,
BlackPPawn, BlackPLance, BlackPKnight, BlackPSilver,
BlackPBishop, BlackPRook, BlackKing,
WhitePPawn, WhitePLance, WhitePKnight, WhitePSilver, WhiteGold,
WhitePBishop, WhitePRook,
WhitePPawn, WhitePLance, WhitePKnight, WhitePSilver,
WhitePBishop, WhitePRook, WhiteKing
};
XrmOptionDescRec shellOptions[] = {
{ "-blackPieceColor", "blackPieceColor", XrmoptionSepArg, NULL },
{ "-wpc", "blackPieceColor", XrmoptionSepArg, NULL },
{ "-whitePieceColor", "whitePieceColor", XrmoptionSepArg, NULL },
{ "-bpc", "whitePieceColor", XrmoptionSepArg, NULL },
{ "-lightSquareColor", "lightSquareColor", XrmoptionSepArg, NULL },
{ "-lsc", "lightSquareColor", XrmoptionSepArg, NULL },
{ "-darkSquareColor", "darkSquareColor", XrmoptionSepArg, NULL },
{ "-dsc", "darkSquareColor", XrmoptionSepArg, NULL },
{ "-movesPerSession", "movesPerSession", XrmoptionSepArg, NULL },
{ "-mps", "movesPerSession", XrmoptionSepArg, NULL },
{ "-firstChessProgram", "firstChessProgram", XrmoptionSepArg, NULL },
{ "-fcp", "firstChessProgram", XrmoptionSepArg, NULL },
{ "-secondChessProgram", "secondChessProgram", XrmoptionSepArg, NULL },
{ "-scp", "secondChessProgram", XrmoptionSepArg, NULL },
{ "-noChessProgram", "noChessProgram", XrmoptionSepArg, NULL },
{ "-ncp", "noChessProgram", XrmoptionSepArg, NULL },
{ "-firstHost", "firstHost", XrmoptionSepArg, NULL },
{ "-fh", "firstHost", XrmoptionSepArg, NULL },
{ "-secondHost", "secondHost", XrmoptionSepArg, NULL },
{ "-sh", "secondHost", XrmoptionSepArg, NULL },
{ "-reversePawnBitmap", "reversePawnBitmap", XrmoptionSepArg, NULL },
{ "-rpb", "reversePawnBitmap", XrmoptionSepArg, NULL },
{ "-reverseLanceBitmap", "reverseLanceBitmap", XrmoptionSepArg, NULL },
{ "-rlb", "reverseLanceBitmap", XrmoptionSepArg, NULL },
{ "-reverseKnightBitmap", "reverseKnightBitmap", XrmoptionSepArg, NULL },
{ "-rnb", "reverseKnightBitmap", XrmoptionSepArg, NULL },
{ "-reverseSilverBitmap", "reverseSilverBitmap", XrmoptionSepArg, NULL },
{ "-rsb", "reverseSilverBitmap", XrmoptionSepArg, NULL },
{ "-reverseGoldBitmap", "reverseGoldBitmap", XrmoptionSepArg, NULL },
{ "-rgb", "reverseGoldBitmap", XrmoptionSepArg, NULL },
{ "-reverseRookBitmap", "reverseRookBitmap", XrmoptionSepArg, NULL },
{ "-rrb", "reverseRookBitmap", XrmoptionSepArg, NULL },
{ "-reverseBishopBitmap", "reverseBishopBitmap", XrmoptionSepArg, NULL },
{ "-rbb", "reverseBishopBitmap", XrmoptionSepArg, NULL },
{ "-reversePPawnBitmap", "reversePPawnBitmap", XrmoptionSepArg, NULL },
{ "-rppb", "reversePPawnBitmap", XrmoptionSepArg, NULL },
{ "-reversePLanceBitmap", "reversePLanceBitmap", XrmoptionSepArg, NULL },
{ "-rplb", "reversePLanceBitmap", XrmoptionSepArg, NULL },
{ "-reversePKnightBitmap", "reversePKnightBitmap", XrmoptionSepArg, NULL },
{ "-rpnb", "reversePKnightBitmap", XrmoptionSepArg, NULL },
{ "-reversePSilverBitmap", "reversePSilverBitmap", XrmoptionSepArg, NULL },
{ "-rpsb", "reversePSilverBitmap", XrmoptionSepArg, NULL },
{ "-reversePRookBitmap", "reversePRookBitmap", XrmoptionSepArg, NULL },
{ "-rprb", "reversePRookBitmap", XrmoptionSepArg, NULL },
{ "-reversePBishopBitmap", "reversePBishopBitmap", XrmoptionSepArg, NULL },
{ "-rpbb", "reversePBishopBitmap", XrmoptionSepArg, NULL },
{ "-reverseKingBitmap", "reverseKingBitmap", XrmoptionSepArg, NULL },
{ "-rkb", "reverseKingBitmap", XrmoptionSepArg, NULL },
{ "-outlinePawnBitmap", "outlinePawnBitmap", XrmoptionSepArg, NULL },
{ "-opb", "normalPawnBitmap", XrmoptionSepArg, NULL },
{ "-normalLanceBitmap", "normalLanceBitmap", XrmoptionSepArg, NULL },
{ "-olb", "normalLanceBitmap", XrmoptionSepArg, NULL },
{ "-normalKnightBitmap", "normalKnightBitmap", XrmoptionSepArg, NULL },
{ "-onb", "normalKnightBitmap", XrmoptionSepArg, NULL },
{ "-normalSilverBitmap", "normalSilverBitmap", XrmoptionSepArg, NULL },
{ "-osb", "normalSilverBitmap", XrmoptionSepArg, NULL },
{ "-normalGoldBitmap", "normalGoldBitmap", XrmoptionSepArg, NULL },
{ "-ogb", "normalGoldBitmap", XrmoptionSepArg, NULL },
{ "-normalRookBitmap", "normalRookBitmap", XrmoptionSepArg, NULL },
{ "-orb", "normalRookBitmap", XrmoptionSepArg, NULL },
{ "-normalBishopBitmap", "normalBishopBitmap", XrmoptionSepArg, NULL },
{ "-obb", "normalBishopBitmap", XrmoptionSepArg, NULL },
{ "-normalPPawnBitmap", "normalPPawnBitmap", XrmoptionSepArg, NULL },
{ "-oppb", "normalPPawnBitmap", XrmoptionSepArg, NULL },
{ "-normalPLanceBitmap", "normalPLanceBitmap", XrmoptionSepArg, NULL },
{ "-oplb", "normalPLanceBitmap", XrmoptionSepArg, NULL },
{ "-normalPKnightBitmap", "normalPKnightBitmap", XrmoptionSepArg, NULL },
{ "-opnb", "normalPKnightBitmap", XrmoptionSepArg, NULL },
{ "-normalPSilverBitmap", "normalPSilverBitmap", XrmoptionSepArg, NULL },
{ "-opsb", "normalPSilverBitmap", XrmoptionSepArg, NULL },
{ "-normalPRookBitmap", "normalPRookBitmap", XrmoptionSepArg, NULL },
{ "-oprb", "normalPRookBitmap", XrmoptionSepArg, NULL },
{ "-normalPBishopBitmap", "normalPBishopBitmap", XrmoptionSepArg, NULL },
{ "-opbb", "normalPBishopBitmap", XrmoptionSepArg, NULL },
{ "-normalKingBitmap", "normalKingBitmap", XrmoptionSepArg, NULL },
{ "-okb", "outlineKingBitmap", XrmoptionSepArg, NULL },
{ "-remoteShell", "remoteShell", XrmoptionSepArg, NULL },
{ "-rsh", "remoteShell", XrmoptionSepArg, NULL },
{ "-timeDelay", "timeDelay", XrmoptionSepArg, NULL },
{ "-td", "timeDelay", XrmoptionSepArg, NULL },
{ "-timeControl", "timeControl", XrmoptionSepArg, NULL },
{ "-tc", "timeControl", XrmoptionSepArg, NULL },
{ "-loadGameFile", "loadGameFile", XrmoptionSepArg, NULL },
{ "-lgf", "loadGameFile", XrmoptionSepArg, NULL },
{ "-loadPositionFile", "loadPositionFile", XrmoptionSepArg, NULL },
{ "-lpf", "loadPositionFile", XrmoptionSepArg, NULL },
{ "-saveGameFile", "saveGameFile", XrmoptionSepArg, NULL },
{ "-sgf", "saveGameFile", XrmoptionSepArg, NULL },
{ "-savePositionFile", "savePositionFile", XrmoptionSepArg, NULL },
{ "-spf", "savePositionFile", XrmoptionSepArg, NULL },
{ "-matchMode", "matchMode", XrmoptionSepArg, NULL },
{ "-mm", "matchMode", XrmoptionSepArg, NULL },
{ "-monoMode", "monoMode", XrmoptionSepArg, NULL },
{ "-mono", "monoMode", XrmoptionSepArg, NULL },
{ "-debugMode", "debugMode", XrmoptionSepArg, NULL },
{ "-debug", "debugMode", XrmoptionSepArg, NULL },
{ "-clockMode", "clockMode", XrmoptionSepArg, NULL },
{ "-clock", "clockMode", XrmoptionSepArg, NULL },
{ "-boardSize", "boardSize", XrmoptionSepArg, NULL },
{ "-size", "boardSize", XrmoptionSepArg, NULL },
{ "-searchTime", "searchTime", XrmoptionSepArg, NULL },
{ "-st", "searchTime", XrmoptionSepArg, NULL },
{ "-searchDepth", "searchDepth", XrmoptionSepArg, NULL },
{ "-sd", "searchDepth", XrmoptionSepArg, NULL },
{ "-showCoords", "showCoords", XrmoptionSepArg, NULL },
{ "-coords", "showCoords", XrmoptionSepArg, NULL },
{ "-iconic", "Iconic", XrmoptionNoArg, "True" }
};
XtActionsRec boardActions[] = {
{ "DrawPosition", (XtActionProc) DrawPosition },
{ "HandleUserMove", (XtActionProc) HandleUserMove },
{ "ResetProc", (XtActionProc) ResetProc },
{ "ResetFileProc", (XtActionProc) ResetFileProc },
{ "GameProc", (XtActionProc) GameProc },
{ "QuitProc", (XtActionProc) QuitProc },
{ "ForwardProc", (XtActionProc) ForwardProc },
{ "BackwardProc", (XtActionProc) BackwardProc },
{ "PauseProc", (XtActionProc) PauseProc },
{ "Iconify", (XtActionProc) Iconify },
{ "FileNameAction", (XtActionProc) FileNameAction },
{ "PieceMenuPopup", (XtActionProc) PieceMenuPopup },
{ "SetBlackToPlay", (XtActionProc) SetBlackToPlay },
{ "SetWhiteToPlay", (XtActionProc) SetWhiteToPlay }
};
char translationsTable[] =
"<Expose>: DrawPosition() \n \
<Btn1Down>: HandleUserMove() \n \
<Btn1Up>: HandleUserMove() \n \
<Btn2Down>: XawPositionSimpleMenu(menuW) PieceMenuPopup(menuW) \n \
<Btn3Down>: XawPositionSimpleMenu(menuB) PieceMenuPopup(menuB) \n \
<Key>r: ResetFileProc() ResetProc() \n \
<Key>R: ResetFileProc() ResetProc() \n \
<Key>g: GameProc() \n \
<Key>G: GameProc() \n \
<Key>q: QuitProc() \n \
<Key>Q: QuitProc() \n \
<Message>WM_PROTOCOLS: QuitProc() \n \
<Key>f: ForwardProc() \n \
<Key>F: ForwardProc() \n \
<Key>b: BackwardProc() \n \
<Key>B: BackwardProc() \n \
<Key>p: PauseProc() \n \
<Key>P: PauseProc() \n \
<Key>i: Iconify() \n \
<Key>I: Iconify() \n \
<Key>c: Iconify() \n \
<Key>C: Iconify() \n";
char blackTranslations[] = "<BtnDown>: SetBlackToPlay()\n";
char whiteTranslations[] = "<BtnDown>: SetWhiteToPlay()\n";
String xshogiResources[] = {
"*font: -*-helvetica-medium-o-normal--*-140-*-*-*-*-*-*\n",
"*Dialog*value.translations: #override \\n <Key>Return: FileNameAction()",
NULL
};
void
main(argc, argv)
int argc;
char **argv;
{
XSetWindowAttributes window_attributes;
char buf[MSG_SIZ];
Arg args[3];
Dimension timerWidth, boardWidth, commandsWidth, w, h;
setbuf(stdout, NULL); setbuf(stderr, NULL);
programName = strrchr(argv[0], '/');
if (programName == NULL)
programName = argv[0];
else
programName++;
shellWidget = XtAppInitialize(&appContext, "XShogi", shellOptions,
XtNumber(shellOptions), &argc, argv, xshogiResources, NULL, 0);
if (argc > 1)
Usage();
if ((chessDir = (char *) getenv("CHESSDIR")) == NULL) {
chessDir = ".";
} else {
if (chdir(chessDir) != 0) {
fprintf(stderr, "%s: can't cd to CHESSDIR\n",
programName);
perror(chessDir);
exit(1);
}
}
XtGetApplicationResources(shellWidget, &appData, clientResources,
XtNumber(clientResources), NULL, 0);
xshogiDebug = appData.debugMode;
/*
* Determine matchMode state -- poor man's resource converter
*/
if (StrCaseCmp(appData.matchMode, "Init") == 0)
matchMode = MatchInit;
else if (StrCaseCmp(appData.matchMode, "Position") == 0)
matchMode = MatchPosition;
else if (StrCaseCmp(appData.matchMode, "Opening") == 0)
matchMode = MatchOpening;
else if (StrCaseCmp(appData.matchMode, "False") == 0)
matchMode = MatchFalse;
else {
fprintf(stderr, "%s: bad matchMode option %s\n",
programName, appData.matchMode);
Usage();
}
/*
* Parse timeControl resource
*/
if (appData.timeControl != NULL) {
int min, sec, matched;
matched = sscanf(appData.timeControl, "%d:%d", &min, &sec);
if (matched == 1) {
timeControl = min * 60 * 1000;
} else if (matched == 2) {
timeControl = (min * 60 + sec) * 1000;
} else {
fprintf(stderr, "%s: bad timeControl option %s\n",
programName, appData.timeControl);
Usage();
}
}
/*
* Parse searchTime resource
*/
if (appData.searchTime != NULL) {
int min, sec, matched;
matched = sscanf(appData.searchTime, "%d:%d", &min, &sec);
if (matched == 1) {
searchTime = min * 60;
} else if (matched == 2) {
searchTime = min * 60 + sec;
} else {
fprintf(stderr, "%s: bad searchTime option %s\n",
programName, appData.searchTime);
Usage();
}
}
/*
* Determine boardSize
*/
if (StrCaseCmp(appData.boardSize, "Large") == 0)
boardSize = Large;
else if (StrCaseCmp(appData.boardSize, "Medium") == 0)
boardSize = Medium;
else if (StrCaseCmp(appData.boardSize, "Small") == 0)
boardSize = Small;
else {
fprintf(stderr, "%s: bad boardSize option %s\n",
programName, appData.boardSize);
Usage();
}
xDisplay = XtDisplay(shellWidget);
xScreen = DefaultScreen(xDisplay);
if (((DisplayWidth(xDisplay, xScreen) < 800)
|| (DisplayHeight(xDisplay, xScreen) < 800))
&& (boardSize == Large)) {
boardSize = Medium;
}
switch (boardSize) {
case Small:
squareSize = SMALL_SQUARE_SIZE;
break;
case Medium:
squareSize = MEDIUM_SQUARE_SIZE;
break;
case Large:
squareSize = LARGE_SQUARE_SIZE;
break;
}
boardWidth = LINE_GAP + (BOARD_SIZE+4) * (squareSize + LINE_GAP);
XtSetArg(boardArgs[1], XtNwidth, boardWidth);
XtSetArg(boardArgs[2], XtNheight,
LINE_GAP + BOARD_SIZE * (squareSize + LINE_GAP));
if ((appData.searchTime != NULL) || (appData.searchDepth > 0)
|| appData.noChessProgram)
appData.clockMode = False;
/*
* Detect if there are not enough colors are available and adapt.
*/
if (DefaultDepth(xDisplay, xScreen) <= 2)
appData.monoMode = True;
/*
* widget hierarchy
*/
formWidget = XtCreateManagedWidget("form",
formWidgetClass, shellWidget, NULL, 0);
widgetList[0] = blackTimerWidget =
XtCreateWidget("black time:", labelWidgetClass,
formWidget, timerArgs, XtNumber(timerArgs));
widgetList[1] = whiteTimerWidget =
XtCreateWidget("white time:", labelWidgetClass,
formWidget, timerArgs, XtNumber(timerArgs));
widgetList[2] = nameWidget =
XtCreateWidget("", labelWidgetClass,
formWidget, nameArgs, XtNumber(nameArgs));
widgetList[3] = messageWidget =
XtCreateWidget("message", labelWidgetClass, formWidget,
messageArgs, XtNumber(messageArgs));
widgetList[4] = commandsWidget =
XtCreateWidget("commands", listWidgetClass, formWidget,
commandsArgs, XtNumber(commandsArgs));
widgetList[5] = boardWidget =
XtCreateWidget("board", widgetClass, formWidget,
boardArgs, XtNumber(boardArgs));
XtManageChildren(widgetList, XtNumber(widgetList));
/*
* Calculate the width of the timer labels.
*/
XtSetArg(args[0], XtNfont, &labelFont);
XtGetValues(blackTimerWidget, args, 1);
if (appData.clockMode) {
sprintf(buf, "Black: %s ", TimeString(timeControl));
timerWidth = XTextWidth(labelFont, buf, strlen(buf) - 1);
} else
timerWidth = XTextWidth(labelFont, "Black ", 7);
XtSetArg(args[0], XtNwidth, timerWidth);
XtSetValues(blackTimerWidget, args, 1);
XtSetValues(whiteTimerWidget, args, 1);
XtSetArg(args[0], XtNbackground, &timerForegroundPixel);
XtSetArg(args[1], XtNforeground, &timerBackgroundPixel);
XtGetValues(blackTimerWidget, args, 2);
/*
* Calculate the width of the name and message labels.
*/
XtSetArg(args[0], XtNwidth, &commandsWidth);
XtGetValues(commandsWidget, args, 1);
w = (commandsWidth > boardWidth) ? commandsWidth : boardWidth;
XtSetArg(args[0], XtNwidth, w - timerWidth*2 - 12);
XtSetValues(nameWidget, args, 1);
XtSetArg(args[0], XtNwidth, w - 8);
XtSetValues(messageWidget, args, 1);
/*
* formWidget uses these constraints but they are stored
* in the children.
*/
XtSetArg(args[0], XtNfromHoriz, blackTimerWidget);
XtSetValues(whiteTimerWidget, args, 1);
XtSetArg(args[0], XtNfromHoriz, whiteTimerWidget);
XtSetValues(nameWidget, args, 1);
XtSetArg(args[0], XtNfromVert, blackTimerWidget);
XtSetValues(messageWidget, args, 1);
XtSetArg(args[0], XtNfromVert, messageWidget);
XtSetValues(commandsWidget, args, 1);
XtSetArg(args[0], XtNfromVert, commandsWidget);
XtSetValues(boardWidget, args, 1);
XtRealizeWidget(shellWidget);
xBoardWindow = XtWindow(boardWidget);
/*
* Create an icon.
*/
iconPixmap = XCreateBitmapFromData(xDisplay, XtWindow(shellWidget),
icon_bits, icon_width, icon_height);
XtSetArg(args[0], XtNiconPixmap, iconPixmap);
XtSetValues(shellWidget, args, 1);
/*
* Create a cursor for the board widget.
*/
window_attributes.cursor = XCreateFontCursor(xDisplay, XC_hand2);
XChangeWindowAttributes(xDisplay, xBoardWindow,
CWCursor, &window_attributes);
/*
* Inhibit shell resizing.
*/
shellArgs[0].value = (XtArgVal) &w;
shellArgs[1].value = (XtArgVal) &h;
XtGetValues(shellWidget, shellArgs, 2);
shellArgs[4].value = shellArgs[2].value = w;
shellArgs[5].value = shellArgs[3].value = h;
XtSetValues(shellWidget, &shellArgs[2], 4);
black_pixel_is_zero = (XBlackPixel == 0);
CreateGCs();
CreateGrid();
CreatePieces();
CreatePieceMenus();
XtAddCallback(commandsWidget, XtNcallback, SelectCommand, NULL);
XtAppAddActions(appContext, boardActions, XtNumber(boardActions));
XtSetArg(args[0], XtNtranslations,
XtParseTranslationTable(translationsTable));
XtSetValues(boardWidget, &args[0], 1);
XtSetArg(args[0], XtNtranslations,
XtParseTranslationTable(blackTranslations));
XtSetValues(blackTimerWidget, &args[0], 1);
XtSetArg(args[0], XtNtranslations,
XtParseTranslationTable(whiteTranslations));
XtSetValues(whiteTimerWidget, &args[0], 1);
XtAddEventHandler(boardWidget, ExposureMask | ButtonPressMask
| ButtonReleaseMask | Button1MotionMask | KeyPressMask,
False, (XtEventHandler) EventProc, NULL);
sprintf(buf, "xshogi version %s, patchlevel %s based on xboard version %s",
version, patchlevel, XBOARD_VERSION);
/*
* If there is to be a machine match, set it up.
*/
if (matchMode != MatchFalse){
if (appData.noChessProgram) {
fprintf(stderr,
"%s: can't have a match with no chess programs!\n",
programName);
exit(1);
}
DisplayMessage(buf);
TwoMachinesPlayProc();
}
else {
ResetProc();
DisplayMessage(buf);
}
XtAppMainLoop(appContext);
}
void
CreateGCs()
{
XtGCMask value_mask = GCLineWidth | GCLineStyle | GCForeground
| GCBackground | GCFunction | GCPlaneMask;
XGCValues gc_values;
Font coordFontID;
gc_values.plane_mask = AllPlanes;
gc_values.line_width = LINE_GAP;
gc_values.line_style = LineSolid;
gc_values.function = GXcopy;
gc_values.foreground = XBlackPixel(xDisplay, xScreen);
gc_values.background = XBlackPixel(xDisplay, xScreen);
lineGC = XtGetGC(shellWidget, value_mask, &gc_values);
gc_values.background = XWhitePixel(xDisplay, xScreen);
coordGC = XtGetGC(shellWidget, value_mask, &gc_values);
coordFontID = XLoadFont(xDisplay, appData.coordFont);
coordFont = XQueryFont(xDisplay, coordFontID);
XSetFont(xDisplay, coordGC, coordFontID);
if (appData.monoMode) {
gc_values.foreground = XWhitePixel(xDisplay, xScreen);
gc_values.background = XBlackPixel(xDisplay, xScreen);
lightSquareGC = darkSquareGC = wbPieceGC
= XtGetGC(shellWidget, value_mask, &gc_values);
gc_values.foreground = XBlackPixel(xDisplay, xScreen);
gc_values.background = XWhitePixel(xDisplay, xScreen);
bwPieceGC
= XtGetGC(shellWidget, value_mask, &gc_values);
} else {
gc_values.foreground = XWhitePixel(xDisplay, xScreen);
gc_values.background = XBlackPixel(xDisplay, xScreen);
wbPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
gc_values.foreground = XBlackPixel(xDisplay, xScreen);
gc_values.background = XWhitePixel(xDisplay, xScreen);
bwPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
gc_values.foreground = appData.lightSquareColor;
gc_values.background = appData.darkSquareColor;
lightSquareGC = XtGetGC(shellWidget, value_mask, &gc_values);
gc_values.foreground = appData.darkSquareColor;
gc_values.background = appData.lightSquareColor;
darkSquareGC = XtGetGC(shellWidget, value_mask, &gc_values);
gc_values.foreground = appData.blackPieceColor;
gc_values.background = appData.darkSquareColor;
wdPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
gc_values.foreground = appData.blackPieceColor;
gc_values.background = appData.lightSquareColor;
wlPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
gc_values.foreground = appData.whitePieceColor;
gc_values.background = appData.darkSquareColor;
bdPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
gc_values.foreground = appData.whitePieceColor;
gc_values.background = appData.lightSquareColor;
blPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
gc_values.function = (black_pixel_is_zero ? GXand : GXor);
gc_values.foreground = XBlackPixel(xDisplay, xScreen);
gc_values.background = XWhitePixel(xDisplay, xScreen);
charPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
}
}
void
CreatePieces()
{
XSynchronize(xDisplay, True); /* Work-around for xlib/xt
buffering bug */
#ifdef WESTERN_BITMAPS
ReadBitmap(appData.reverseBigSolidBitmap, &reverseBigSolidBitmap,
NULL,
bigsolidR_bits, bigsolidR_bits, bigsolidR_bits);
ReadBitmap(appData.reverseSmallSolidBitmap, &reverseSmallSolidBitmap,
NULL,
smallsolidR_bits, smallsolidR_bits, smallsolidR_bits);
ReadBitmap(appData.normalBigSolidBitmap, &normalBigSolidBitmap,
NULL,
bigsolid_bits, bigsolid_bits, bigsolid_bits);
ReadBitmap(appData.normalSmallSolidBitmap, &normalSmallSolidBitmap,
NULL,
smallsolid_bits, smallsolid_bits, smallsolid_bits);
ReadBitmap(appData.reversePawnBitmap, &reversePawnBitmap,
&reverseSmallSolidBitmap,
pawnR_bits, pawnR_bits, pawnR_bits);
ReadBitmap(appData.reverseLanceBitmap, &reverseLanceBitmap,
&reverseSmallSolidBitmap,
lanceR_bits, lanceR_bits, lanceR_bits);
ReadBitmap(appData.reverseKnightBitmap, &reverseKnightBitmap,
&reverseSmallSolidBitmap,
knightR_bits, knightR_bits, knightR_bits);
ReadBitmap(appData.reverseSilverBitmap, &reverseSilverBitmap,
&reverseBigSolidBitmap,
silverR_bits, silverR_bits, silverR_bits);
ReadBitmap(appData.reverseGoldBitmap, &reverseGoldBitmap,
&reverseBigSolidBitmap,
goldR_bits, goldR_bits, goldR_bits);
ReadBitmap(appData.reverseRookBitmap, &reverseRookBitmap,
&reverseBigSolidBitmap,
rookR_bits, rookR_bits, rookR_bits);
ReadBitmap(appData.reverseBishopBitmap, &reverseBishopBitmap,
&reverseBigSolidBitmap,
bishopR_bits, bishopR_bits, bishopR_bits);
ReadBitmap(appData.reversePPawnBitmap, &reversePPawnBitmap,
&reverseSmallSolidBitmap,
pawnPR_bits, pawnPR_bits, pawnPR_bits);
ReadBitmap(appData.reversePLanceBitmap, &reversePLanceBitmap,
&reverseSmallSolidBitmap,
lancePR_bits, lancePR_bits, lancePR_bits);
ReadBitmap(appData.reversePKnightBitmap, &reversePKnightBitmap,
&reverseSmallSolidBitmap,
knightPR_bits, knightPR_bits, knightPR_bits);
ReadBitmap(appData.reversePSilverBitmap, &reversePSilverBitmap,
&reverseBigSolidBitmap,
silverPR_bits, silverPR_bits, silverPR_bits);
ReadBitmap(appData.reversePRookBitmap, &reversePRookBitmap,
&reverseBigSolidBitmap,
rookPR_bits, rookPR_bits, rookPR_bits);
ReadBitmap(appData.reversePBishopBitmap, &reversePBishopBitmap,
&reverseBigSolidBitmap,
bishopPR_bits, bishopPR_bits, bishopPR_bits);
ReadBitmap(appData.reverseKingBitmap, &reverseKingBitmap,
&reverseBigSolidBitmap,
kingR_bits, kingR_bits, kingR_bits);
ReadBitmap(appData.normalPawnBitmap, &normalPawnBitmap,
&normalSmallSolidBitmap,
pawn_bits, pawn_bits, pawn_bits);
ReadBitmap(appData.normalLanceBitmap, &normalLanceBitmap,
&normalSmallSolidBitmap,
lance_bits, lance_bits, lance_bits);
ReadBitmap(appData.normalKnightBitmap, &normalKnightBitmap,
&normalSmallSolidBitmap,
knight_bits, knight_bits, knight_bits);
ReadBitmap(appData.normalSilverBitmap, &normalSilverBitmap,
&normalBigSolidBitmap,
silver_bits, silver_bits, silver_bits);
ReadBitmap(appData.normalGoldBitmap, &normalGoldBitmap,
&normalBigSolidBitmap,
gold_bits, gold_bits, gold_bits);
ReadBitmap(appData.normalRookBitmap, &normalRookBitmap,
&normalBigSolidBitmap,
rook_bits, rook_bits, rook_bits);
ReadBitmap(appData.normalBishopBitmap, &normalBishopBitmap,
&normalBigSolidBitmap,
bishop_bits, bishop_bits, bishop_bits);
ReadBitmap(appData.normalPPawnBitmap, &normalPPawnBitmap,
&normalSmallSolidBitmap,
pawnP_bits, pawnP_bits, pawnP_bits);
ReadBitmap(appData.normalPLanceBitmap, &normalPLanceBitmap,
&normalSmallSolidBitmap,
lanceP_bits, lanceP_bits, lanceP_bits);
ReadBitmap(appData.normalPKnightBitmap, &normalPKnightBitmap,
&normalSmallSolidBitmap,
knightP_bits, knightP_bits, knightP_bits);
ReadBitmap(appData.normalPSilverBitmap, &normalPSilverBitmap,
&normalBigSolidBitmap,
silverP_bits, silverP_bits, silverP_bits);
ReadBitmap(appData.normalPRookBitmap, &normalPRookBitmap,
&normalBigSolidBitmap,
rookP_bits, rookP_bits, rookP_bits);
ReadBitmap(appData.normalPBishopBitmap, &normalPBishopBitmap,
&normalBigSolidBitmap,
bishopP_bits, bishopP_bits, bishopP_bits);
ReadBitmap(appData.normalKingBitmap, &normalKingBitmap,
&normalBigSolidBitmap,
king_bits, king_bits, king_bits);
#else
ReadBitmap(appData.reverseBigSolidBitmap, &reverseBigSolidBitmap,
NULL,
bigsolidR_bits, bigsolidR_m_bits, bigsolidR_l_bits);
ReadBitmap(appData.reverseSmallSolidBitmap, &reverseSmallSolidBitmap,
NULL,
smallsolidR_bits, smallsolidR_m_bits, smallsolidR_l_bits);
ReadBitmap(appData.normalBigSolidBitmap, &normalBigSolidBitmap,
NULL,
bigsolid_bits, bigsolid_m_bits, bigsolid_l_bits);
ReadBitmap(appData.normalSmallSolidBitmap, &normalSmallSolidBitmap,
NULL,
smallsolid_bits, smallsolid_m_bits, smallsolid_l_bits);
ReadBitmap(appData.reversePawnBitmap, &reversePawnBitmap,
&reverseSmallSolidBitmap,
pawnR_bits, pawnR_m_bits, pawnR_l_bits);
ReadBitmap(appData.reverseLanceBitmap, &reverseLanceBitmap,
&reverseSmallSolidBitmap,
lanceR_bits, lanceR_m_bits, lanceR_l_bits);
ReadBitmap(appData.reverseKnightBitmap, &reverseKnightBitmap,
&reverseSmallSolidBitmap,
knightR_bits, knightR_m_bits, knightR_l_bits);
ReadBitmap(appData.reverseSilverBitmap, &reverseSilverBitmap,
&reverseBigSolidBitmap,
silverR_bits, silverR_m_bits, silverR_l_bits);
ReadBitmap(appData.reverseGoldBitmap, &reverseGoldBitmap,
&reverseBigSolidBitmap,
goldR_bits, goldR_m_bits, goldR_l_bits);
ReadBitmap(appData.reverseRookBitmap, &reverseRookBitmap,
&reverseBigSolidBitmap,
rookR_bits, rookR_m_bits, rookR_l_bits);
ReadBitmap(appData.reverseBishopBitmap, &reverseBishopBitmap,
&reverseBigSolidBitmap,
bishopR_bits, bishopR_m_bits, bishopR_l_bits);
ReadBitmap(appData.reversePPawnBitmap, &reversePPawnBitmap,
&reverseSmallSolidBitmap,
pawnPR_bits, pawnPR_m_bits, pawnPR_l_bits);
ReadBitmap(appData.reversePLanceBitmap, &reversePLanceBitmap,
&reverseSmallSolidBitmap,
lancePR_bits, lancePR_m_bits, lancePR_l_bits);
ReadBitmap(appData.reversePKnightBitmap, &reversePKnightBitmap,
&reverseSmallSolidBitmap,
knightPR_bits, knightPR_m_bits, knightPR_l_bits);
ReadBitmap(appData.reversePSilverBitmap, &reversePSilverBitmap,
&reverseBigSolidBitmap,
silverPR_bits, silverPR_m_bits, silverPR_l_bits);
ReadBitmap(appData.reversePRookBitmap, &reversePRookBitmap,
&reverseBigSolidBitmap,
rookPR_bits, rookPR_m_bits, rookPR_l_bits);
ReadBitmap(appData.reversePBishopBitmap, &reversePBishopBitmap,
&reverseBigSolidBitmap,
bishopPR_bits, bishopPR_m_bits, bishopPR_l_bits);
ReadBitmap(appData.reverseKingBitmap, &reverseKingBitmap,
&reverseBigSolidBitmap,
kingR_bits, kingR_m_bits, kingR_l_bits);
ReadBitmap(appData.normalPawnBitmap, &normalPawnBitmap,
&normalSmallSolidBitmap,
pawn_bits, pawn_m_bits, pawn_l_bits);
ReadBitmap(appData.normalLanceBitmap, &normalLanceBitmap,
&normalSmallSolidBitmap,
lance_bits, lance_m_bits, lance_l_bits);
ReadBitmap(appData.normalKnightBitmap, &normalKnightBitmap,
&normalSmallSolidBitmap,
knight_bits, knight_m_bits, knight_l_bits);
ReadBitmap(appData.normalSilverBitmap, &normalSilverBitmap,
&normalBigSolidBitmap,
silver_bits, silver_m_bits, silver_l_bits);
ReadBitmap(appData.normalGoldBitmap, &normalGoldBitmap,
&normalBigSolidBitmap,
gold_bits, gold_m_bits, gold_l_bits);
ReadBitmap(appData.normalRookBitmap, &normalRookBitmap,
&normalBigSolidBitmap,
rook_bits, rook_m_bits, rook_l_bits);
ReadBitmap(appData.normalBishopBitmap, &normalBishopBitmap,
&normalBigSolidBitmap,
bishop_bits, bishop_m_bits, bishop_l_bits);
ReadBitmap(appData.normalPPawnBitmap, &normalPPawnBitmap,
&normalSmallSolidBitmap,
pawnP_bits, pawnP_m_bits, pawnP_l_bits);
ReadBitmap(appData.normalPLanceBitmap, &normalPLanceBitmap,
&normalSmallSolidBitmap,
lanceP_bits, lanceP_m_bits, lanceP_l_bits);
ReadBitmap(appData.normalPKnightBitmap, &normalPKnightBitmap,
&normalSmallSolidBitmap,
knightP_bits, knightP_m_bits, knightP_l_bits);
ReadBitmap(appData.normalPSilverBitmap, &normalPSilverBitmap,
&normalBigSolidBitmap,
silverP_bits, silverP_m_bits, silverP_l_bits);
ReadBitmap(appData.normalPRookBitmap, &normalPRookBitmap,
&normalBigSolidBitmap,
rookP_bits, rookP_m_bits, rookP_l_bits);
ReadBitmap(appData.normalPBishopBitmap, &normalPBishopBitmap,
&normalBigSolidBitmap,
bishopP_bits, bishopP_m_bits, bishopP_l_bits);
ReadBitmap(appData.normalKingBitmap, &normalKingBitmap,
&normalBigSolidBitmap,
king_bits, king_m_bits, king_l_bits);
#endif
XSynchronize(xDisplay, False); /* Work-around for xlib/xt
buffering bug */
}
int
ReadBitmapFile(display, d, filename, width_return,
height_return, bitmap_return,
x_hot_return, y_hot_return)
Display *display;
Drawable d;
char *filename;
unsigned int *width_return, *height_return;
Pixmap *bitmap_return;
int *x_hot_return, *y_hot_return;
{
int n;
if ((n = XReadBitmapFile(display, d, filename,
width_return, height_return, bitmap_return, x_hot_return, y_hot_return))
!= BitmapSuccess)
return(n);
else
{
/* transform a 1 plane pixmap to a k plane pixmap */
return(BitmapSuccess);
}
}
void
ReadBitmap(name, pm, qm, small_bits, medium_bits, large_bits)
String name;
Pixmap *pm, *qm;
char small_bits[], medium_bits[], large_bits[];
{
int x_hot, y_hot;
u_int w, h;
if (name == NULL || ReadBitmapFile(xDisplay, xBoardWindow, name,
&w, &h, pm, &x_hot, &y_hot) != BitmapSuccess
|| w != squareSize || h != squareSize) {
unsigned long fg, bg;
unsigned int depth;
depth = DisplayPlanes(xDisplay, xScreen);
if ( appData.monoMode ) {
fg = XBlackPixel(xDisplay, xScreen);
bg = XWhitePixel(xDisplay, xScreen);
} else if ( qm == NULL ) {
fg = appData.whitePieceColor;
bg = appData.lightSquareColor;
} else {
fg = (black_pixel_is_zero ? 0 : ~0);
bg = (black_pixel_is_zero ? ~0 : 0);
};
switch (boardSize) {
case Large:
*pm = XCreatePixmapFromBitmapData(xDisplay, xBoardWindow,
large_bits, squareSize, squareSize,
fg, bg, depth);
break;
case Medium:
*pm = XCreatePixmapFromBitmapData(xDisplay, xBoardWindow,
medium_bits, squareSize, squareSize,
fg, bg, depth);
break;
case Small:
*pm = XCreatePixmapFromBitmapData(xDisplay, xBoardWindow,
small_bits, squareSize, squareSize,
fg, bg, depth);
break;
}
}
}
void
CreateGrid()
{
int i, offset;
offset = 2 * (squareSize + LINE_GAP);
for (i = 0; i < BOARD_SIZE + 1; i++) {
gridSegments[i].x1 = offset;
gridSegments[i + BOARD_SIZE + 1].y1 = 0;
gridSegments[i].y1 = gridSegments[i].y2
= LINE_GAP / 2 + (i * (squareSize + LINE_GAP));
gridSegments[i].x2 = LINE_GAP + BOARD_SIZE *
(squareSize + LINE_GAP) + offset;
gridSegments[i + BOARD_SIZE + 1].x1 =
gridSegments[i + BOARD_SIZE + 1].x2 = LINE_GAP / 2
+ (i * (squareSize + LINE_GAP)) + offset;
gridSegments[i + BOARD_SIZE + 1].y2 =
BOARD_SIZE * (squareSize + LINE_GAP);
}
}
void
CreatePieceMenus()
{
int i;
Widget entry;
Arg args[1];
ChessSquare selection;
XtSetArg(args[0], XtNlabel, "Black");
blackPieceMenu = XtCreatePopupShell("menuW", simpleMenuWidgetClass,
boardWidget, args, 1);
for (i = 0; i < PIECE_MENU_SIZE; i++) {
String item = pieceMenuStrings[i];
if (strcmp(item, "----") == 0) {
entry = XtCreateManagedWidget(item, smeLineObjectClass,
blackPieceMenu, NULL, 0);
} else {
entry = XtCreateManagedWidget(item, smeBSBObjectClass,
blackPieceMenu, NULL, 0);
selection = pieceMenuTranslation[0][i];
XtAddCallback(entry, XtNcallback,
(XtCallbackProc) PieceMenuSelect,
(caddr_t) selection);
if (selection == BlackPawn) {
XtSetArg(args[0], XtNpopupOnEntry, entry);
XtSetValues(blackPieceMenu, args, 1);
}
}
}
XtSetArg(args[0], XtNlabel, "White");
whitePieceMenu = XtCreatePopupShell("menuB", simpleMenuWidgetClass,
boardWidget, args, 1);
for (i = 0; i < PIECE_MENU_SIZE; i++) {
String item = pieceMenuStrings[i];
if (strcmp(item, "----") == 0) {
entry = XtCreateManagedWidget(item, smeLineObjectClass,
whitePieceMenu, NULL, 0);
} else {
entry = XtCreateManagedWidget(item, smeBSBObjectClass,
whitePieceMenu, NULL, 0);
selection = pieceMenuTranslation[1][i];
XtAddCallback(entry, XtNcallback,
(XtCallbackProc) PieceMenuSelect,
(caddr_t) selection);
if (selection == WhitePawn) {
XtSetArg(args[0], XtNpopupOnEntry, entry);
XtSetValues(whitePieceMenu, args, 1);
}
}
}
XtRegisterGrabAction(PieceMenuPopup, True,
(unsigned)(ButtonPressMask|ButtonReleaseMask),
GrabModeAsync, GrabModeAsync);
}
void
PieceMenuPopup(w, event, params, num_params)
Widget w;
XEvent *event;
String *params;
Cardinal *num_params;
{
if (event->type != ButtonPress) return;
if (gameMode != EditPosition) return;
if (((pmFromX = EventToXSquare(event->xbutton.x)) < 1) ||
(pmFromX > BOARD_SIZE+2) ||
((pmFromY = EventToSquare(event->xbutton.y)) < 0)) {
pmFromX = pmFromY = -1;
return;
}
if (flipView)
pmFromX = BOARD_SIZE + 3 - pmFromX;
else
pmFromY = BOARD_SIZE - 1 - pmFromY;
XtPopupSpringLoaded(XtNameToWidget(boardWidget, params[0]));
}
static void
PieceMenuSelect(w, piece, junk)
Widget w;
ChessSquare piece;
caddr_t junk;
{
if (pmFromX < 0 || pmFromY < 0) return;
if (off_board(pmFromX) ) {
int i, c;
switch (piece) {
case ClearBoard:
break;
case BlackPlay:
break;
case WhitePlay:
break;
default:
i = pieceToCatchedIndex[piece];
c = (piece >= WhitePawn );
catches[0][c][i]++;
UpdateCatched(c, i, True, False, 0);
XSync(xDisplay, False);
return;
}
}
pmFromX -= 2;
switch (piece) {
case ClearBoard:
for (pmFromY = 0; pmFromY < BOARD_SIZE; pmFromY++)
for (pmFromX = 0; pmFromX < BOARD_SIZE; pmFromX++) {
boards[0][pmFromY][pmFromX] = EmptySquare;
DrawSquare(pmFromY, pmFromX, EmptySquare);
}
ClearCatches(catches[0]);
UpdateCatched(0,0,False,True, 0);
UpdateCatched(1,0,False,True, 0);
break;
case BlackPlay: /*not currently on menu*/
SetBlackToPlay();
break;
case WhitePlay: /*not currently on menu*/
SetWhiteToPlay();
break;
default:
boards[0][pmFromY][pmFromX] = piece;
DrawSquare(pmFromY, pmFromX, piece);
break;
}
XSync(xDisplay, False);
}
static void
SetBlackToPlay()
{
int saveCM;
if (gameMode != EditPosition) return;
whitePlaysFirst = False;
saveCM = currentMove;
currentMove = 0; /*kludge*/
DisplayClocks(ReDisplayTimers);
currentMove = saveCM;
}
static void
SetWhiteToPlay()
{
int saveCM;
if (gameMode != EditPosition) return;
whitePlaysFirst = True;
saveCM = currentMove;
currentMove = 1; /*kludge*/
DisplayClocks(ReDisplayTimers);
currentMove = saveCM;
}
/*
* If the user selects on a border boundary or off the board, return failure.
* Otherwise map the event coordinate to the square.
*/
int
EventToSquare(x)
int x;
{
if (x < LINE_GAP)
return -1;
x -= LINE_GAP;
if ((x % (squareSize + LINE_GAP)) >= squareSize)
return -1;
x /= (squareSize + LINE_GAP);
if (x >= BOARD_SIZE)
return -1;
return x;
}
int
EventToXSquare(x)
int x;
{
if (x < LINE_GAP)
return -1;
x -= LINE_GAP;
if ((x % (squareSize + LINE_GAP)) >= squareSize)
return -1;
x /= (squareSize + LINE_GAP);
if (x >= BOARD_SIZE+4)
return -1;
return x;
}
ChessSquare
CharToPiece(c, p)
int c;
int p;
{
if ( p )
switch (c) {
default:
case '.': return EmptySquare;
case 'P': return BlackPPawn;
case 'L': return BlackPLance;
case 'N': return BlackPKnight;
case 'S': return BlackPSilver;
case 'G': return BlackGold;
case 'R': return BlackPRook;
case 'B': return BlackPBishop;
case 'K': return BlackKing;
case 'p': return WhitePPawn;
case 'l': return WhitePLance;
case 'n': return WhitePKnight;
case 's': return WhitePSilver;
case 'g': return WhiteGold;
case 'r': return WhitePRook;
case 'b': return WhitePBishop;
case 'k': return WhiteKing;
}
else
switch (c) {
default:
case '.': return EmptySquare;
case 'P': return BlackPawn;
case 'L': return BlackLance;
case 'N': return BlackKnight;
case 'S': return BlackSilver;
case 'G': return BlackGold;
case 'R': return BlackRook;
case 'B': return BlackBishop;
case 'K': return BlackKing;
case 'p': return WhitePawn;
case 'l': return WhiteLance;
case 'n': return WhiteKnight;
case 's': return WhiteSilver;
case 'g': return WhiteGold;
case 'r': return WhiteRook;
case 'b': return WhiteBishop;
case 'k': return WhiteKing;
}
}
/* Convert coordinates to normal algebraic notation.
promoPiece must be '\000' if not a promotion.
*/
ChessMove
MakeAlg(fromX, fromY, toX, toY, promoPiece, currentBoardIndex, out)
int fromX, fromY, toX, toY;
char promoPiece;
int currentBoardIndex;
char out[MOVE_LEN];
{
ChessSquare piece;
ChessMove ret;
char *outp = out;
int i;
if ( fromX > 80 ) {
ChessSquare piece;
piece = (fromX - 81);
*outp++ = catchedIndexToChar[piece];
*outp++ = '*';
*outp++ = '9' - toX;
*outp++ = 'i' - toY;
*outp++ = '\000';
return (BLACK_ON_MOVE ? BlackDrop : WhiteDrop);
} else {
*outp++ = '9' - fromX;
*outp++ = 'i' - fromY;
*outp++ = '9' - toX;
*outp++ = 'i' - toY;
*outp++ = promoPiece;
*outp++ = '\000';
if ( promoPiece == '\000' )
return NormalMove;
else
return (BLACK_ON_MOVE ? BlackPromotion : WhitePromotion);
}
}
void
DrawSquare(row, column, piece)
int row, column;
ChessSquare piece;
{
int square_color, x, y, direction, font_ascent, font_descent;
char string[2];
XCharStruct overall;
int offset;
offset = 2 * (squareSize + LINE_GAP);
if (flipView) {
x = LINE_GAP + ((BOARD_SIZE-1)-column) *
(squareSize + LINE_GAP) + offset;
y = LINE_GAP + row * (squareSize + LINE_GAP);
} else {
x = LINE_GAP + column * (squareSize + LINE_GAP) + offset;
y = LINE_GAP + ((BOARD_SIZE-1)-row) *
(squareSize + LINE_GAP);
}
square_color = ((column + row) % 2) == 1;
if (piece == EmptySquare) {
if ( column < 0 || column >= BOARD_SIZE )
XFillRectangle(xDisplay, xBoardWindow,
wbPieceGC,
x, y, squareSize, squareSize);
else
XFillRectangle(xDisplay, xBoardWindow,
square_color ? lightSquareGC : darkSquareGC,
x, y, squareSize, squareSize);
} else if (appData.monoMode || column < 0 || column >= BOARD_SIZE) {
if (square_color)
XCopyArea(xDisplay, ((int) piece < (int) WhitePawn) ^ flipView
? *pieceToNormal[(int) piece]
: *pieceToReverse[(int) piece],
xBoardWindow,
(appData.monoMode ? wbPieceGC : wlPieceGC),
0, 0,
squareSize, squareSize, x, y);
else
XCopyArea(xDisplay, ((int) piece < (int) WhitePawn) ^ flipView
? *pieceToNormal[(int) piece]
: *pieceToReverse[(int) piece],
xBoardWindow,
(appData.monoMode ? bwPieceGC : wlPieceGC),
0, 0,
squareSize, squareSize, x, y);
} else {
if (square_color) {
XCopyArea(xDisplay, ((int) piece < (int) WhitePawn) ^ flipView
? *pieceToNormalSolid[(int) piece]
: *pieceToReverseSolid[(int) piece],
xBoardWindow,
wlPieceGC,
0, 0,
squareSize, squareSize, x, y);
XCopyArea(xDisplay, ((int) piece < (int) WhitePawn) ^ flipView
? *pieceToNormal[(int) piece]
: *pieceToReverse[(int) piece],
xBoardWindow,
charPieceGC,
0, 0,
squareSize, squareSize, x, y);
} else {
XCopyArea(xDisplay, ((int) piece < (int) WhitePawn) ^ flipView
? *pieceToNormalSolid[(int) piece]
: *pieceToReverseSolid[(int) piece],
xBoardWindow,
wlPieceGC,
0, 0,
squareSize, squareSize, x, y);
XCopyArea(xDisplay, ((int) piece < (int) WhitePawn) ^ flipView
? *pieceToNormal[(int) piece]
: *pieceToReverse[(int) piece],
xBoardWindow,
charPieceGC,
0, 0,
squareSize, squareSize, x, y);
}
}
string[1] = '\000';
if (appData.showCoords && column >= 0 && column < 9 && row == (flipView ? 8 : 0)) {
string[0] = '9' - column;
XTextExtents(coordFont, string, 1, &direction,
&font_ascent, &font_descent, &overall);
if (appData.monoMode) {
XDrawImageString(xDisplay, xBoardWindow, coordGC,
x + squareSize - overall.width - 2,
y + squareSize - font_descent - 1, string, 1);
} else {
XDrawString(xDisplay, xBoardWindow, coordGC,
x + squareSize - overall.width - 2,
y + squareSize - font_descent - 1, string, 1);
}
}
if (appData.showCoords && row >= 0 && row < 9 && column == (flipView ? 8 : 0)) {
string[0] = 'i' - row;
XTextExtents(coordFont, string, 1, &direction,
&font_ascent, &font_descent, &overall);
if (appData.monoMode) {
XDrawImageString(xDisplay, xBoardWindow, coordGC,
x + 2, y + font_ascent + 1, string, 1);
} else {
XDrawString(xDisplay, xBoardWindow, coordGC,
x + 2, y + font_ascent + 1, string, 1);
}
}
}
void
EventProc(widget, unused, event)
Widget widget;
caddr_t unused;
XEvent *event;
{
if (event->type == MappingNotify) {
XRefreshKeyboardMapping((XMappingEvent *) event);
return;
}
if (!XtIsRealized(widget))
return;
if ((event->type == ButtonPress) || (event->type == ButtonRelease))
if (event->xbutton.button != Button1)
return;
switch (event->type) {
case Expose:
DrawPosition(widget, (XExposeEvent *) event);
break;
default:
return;
}
}
/*
* event handler for redrawing the board
*/
void
DrawPosition(w, event)
Widget w;
XExposeEvent *event;
{
Arg args[1];
int i, j;
if (!appData.Iconic){
XtSetArg(args[0], XtNiconic, False);
XtSetValues(shellWidget, args, 1);
}
/*
* It would be simpler to clear the window with XClearWindow()
* but this causes a very distracting flicker.
*/
XDrawSegments(xDisplay, xBoardWindow, lineGC,
gridSegments, (BOARD_SIZE + 1) * 2);
for (i = 0; i < BOARD_SIZE; i++)
for (j = 0; j < BOARD_SIZE; j++)
DrawSquare(i, j, boards[currentMove][i][j]);
UpdateCatched(0,0,False,True,currentMove);
UpdateCatched(1,0,False,True,currentMove);
XSync(xDisplay, False);
}
void
InitPosition()
{
currentMove = forwardMostMove = 0;
CopyBoard(boards[0], initialPosition);
ClearCatches(catches[0]);
DrawPosition(boardWidget, (XExposeEvent *) NULL);
}
void
CopyBoard(to, from)
Board to, from;
{
int i, j;
for (i = 0; i < BOARD_SIZE; i++)
for (j = 0; j < BOARD_SIZE; j++)
to[i][j] = from[i][j];
}
void
CopyCatches(to, from)
Catched to, from;
{
int i, j;
for (i = 0; i < 2; i++)
for (j = 0; j < 8; j++)
to[i][j] = from[i][j];
}
void
SendCurrentBoard(fp)
FILE *fp;
{
SendBoard(fp, boards[currentMove], catches[currentMove]);
}
void
SendBoard(fp, board, catches)
FILE *fp;
Board board;
Catched catches;
{
char message[MSG_SIZ];
ChessSquare *bp;
int i, j;
SendToProgram("edit\n", fp);
SendToProgram("#\n", fp);
for (i = BOARD_SIZE - 1; i >= 0; i--) {
bp = &board[i][0];
for (j = 0; j < BOARD_SIZE; j++, bp++) {
if ((int) *bp < (int) WhitePawn) {
sprintf(message, "%c%c%c\n",
pieceToChar[(int) *bp],
'9' - j, 'i' - i);
SendToProgram(message, fp);
}
}
}
for ( i = 0; i <= 7; i++ ) {
int n;
for ( n = catches[0][i]; n > 0; n-- ) {
sprintf(message, "%c*\n",
catchedIndexToChar[i]);
SendToProgram(message, fp);
};
}
SendToProgram("c\n", fp);
for (i = BOARD_SIZE - 1; i >= 0; i--) {
bp = &board[i][0];
for (j = 0; j < BOARD_SIZE; j++, bp++) {
if (((int) *bp != (int) EmptySquare)
&& ((int) *bp >= (int) WhitePawn)) {
sprintf(message, "%c%c%c\n",
pieceToChar[(int) *bp -
(int) WhitePawn],
'9' - j, 'i' - i);
SendToProgram(message, fp);
}
}
}
for ( i = 0; i <= 7; i++ ) {
int n;
for ( n = catches[1][i]; n > 0; n-- ) {
sprintf(message, "%c*\n",
catchedIndexToChar[i]);
SendToProgram(message, fp);
};
}
SendToProgram(".\n", fp);
}
static
int
PromotionPossible (fromY, toY, piece)
int fromY, toY;
ChessSquare piece;
{
if ( (int) piece < (int) WhitePawn ) {
if ( fromY < 6 && toY < 6 ) return(False);
} else {
if ( fromY > 2 && toY > 2 ) return(False);
};
return piecePromotable[(int) piece];
}
static
void
ShowCount (row, column, n)
int row, column, n;
{
int offset = 2 * (squareSize + LINE_GAP);
int x, y, direction, font_ascent, font_descent;
char string[2];
XCharStruct overall;
DrawSquare (row, column, EmptySquare);
if ( n <= 1 ) {
return;
};
if (flipView) {
x = LINE_GAP + ((BOARD_SIZE-1)-column) *
(squareSize + LINE_GAP) + offset;
y = LINE_GAP + row * (squareSize + LINE_GAP);
} else {
x = LINE_GAP + column * (squareSize + LINE_GAP) + offset;
y = LINE_GAP + ((BOARD_SIZE-1)-row) *
(squareSize + LINE_GAP);
}
x -= squareSize / 2;
string[1] = '\000';
if ( n > 9 )
string[0] = '*';
else
string[0] = '0'+n;
XTextExtents(coordFont, string, 1, &direction,
&font_ascent, &font_descent, &overall);
if (appData.monoMode) {
XDrawImageString(xDisplay, xBoardWindow, coordGC,
x + squareSize - overall.width - 2,
y + squareSize - font_descent - 1, string, 1);
} else {
XDrawString(xDisplay, xBoardWindow, coordGC,
x + squareSize - overall.width - 2,
y + squareSize - font_descent - 1, string, 1);
}
}
void UpdateCatched (Color,Figure,Drop,DropAll,currentMove)
int Color,Figure,Drop,DropAll,currentMove;
{
int n,F,C;
int x,y;
/* Determine first row and column. */
if ( Color ) {
x = -1; y = BOARD_SIZE-1;
} else {
x = BOARD_SIZE; y = 0;
};
if ( DropAll )
n = 0;
else
n = catches[currentMove][Color][Figure];
/* Update the display for captured pieces
if no piece of the dropped type is there (Drop && n==1)
or if a piece type is removed (NOT Drop && n==0).
In the other cases update only the count. */
if ( DropAll || (Drop && (n==1)) || ((! Drop) && (n==0)) ) {
/* show all captured pieces */
n = 0;
for ( F = pawn; F<=king; F++ ) {
int c;
if ( (c=catches[currentMove][Color][F])>0 ) {
n++;
DrawSquare(y, x, catchedIndexToPiece[Color][F]);
ShowCount(y, Color ? (x-1) : (x+1), c);
if ( Color ) y--; else y++;
};
};
if ( DropAll ) {
for ( ; n < 9; n++ ) {
DrawSquare(y, x, EmptySquare);
ShowCount(y, Color ? (x-1) : (x+1), 0);
if ( Color ) y--; else y++;
}
} else if ( ! Drop ) {
/* remove one line ! */
DrawSquare(y, x, EmptySquare);
ShowCount(y, Color ? (x-1) : (x+1), 0);
};
} else {
/* show the actual count */
for ( F = pawn; F <= Figure-1; F++ ) {
if ( catches[currentMove][Color][F] > 0 ) {
if ( Color ) y--; else y++;
};
};
ShowCount(y, Color ? (x-1) : (x+1), n);
};
};
static
int
PieceOfCatched (color, x, y, currentMove)
int color, x, y, currentMove;
{
int F, n;
if ( color ) {
if ( x != 1 ) return (no_piece);
y = 8 - y;
} else {
if ( x != 11 ) return (no_piece);
};
for ( F = pawn, n = 0; F <= king; F++ ) {
if ( catches[currentMove][color][F] > 0 ) {
if ( n == y ) return (F);
n++;
};
};
return (no_piece);
}
/*
* event handler for parsing user moves
*/
void
HandleUserMove(w, event)
Widget w;
XEvent *event;
{
ChessMove move_type;
ChessSquare from_piece;
int to_x, to_y;
if ((w != boardWidget) || (matchMode != MatchFalse))
return;
if (promotionUp) {
XtPopdown(promotionShell);
XtDestroyWidget(promotionShell);
promotionUp = False;
fromX = fromY = -1;
}
switch (gameMode) {
case EndOfGame:
case PlayFromGameFile:
case TwoMachinesPlay:
return;
case MachinePlaysBlack:
if (BLACK_ON_MOVE)
return;
break;
case MachinePlaysWhite:
if (!BLACK_ON_MOVE)
return;
break;
default:
break;
}
switch (event->type) {
case ButtonPress:
if ((fromX >= 0) || (fromY >= 0))
return;
if (((fromX = EventToXSquare(event->xbutton.x)) < 1) ||
(fromX > BOARD_SIZE+2) ||
((fromY = EventToSquare(event->xbutton.y)) < 0)) {
fromX = fromY = -1;
return;
}
if (flipView)
fromX = BOARD_SIZE + 3 - fromX;
else
fromY = BOARD_SIZE - 1 - fromY;
break;
case ButtonRelease:
if ((fromX < 0) || (fromY < 0)) return;
if (((to_x = EventToXSquare(event->xbutton.x)) < 1)
|| (to_x > BOARD_SIZE+2)
|| ((to_y = EventToSquare(event->xbutton.y)) < 0)) {
if (gameMode == EditPosition)
if ( !off_board(fromX) )
{
fromX -= 2;
boards[0][fromY][fromX] = EmptySquare;
DrawSquare(fromY, fromX, EmptySquare);
XSync(xDisplay, False);
}
fromX = fromY = -1;
return;
}
if (flipView)
to_x = BOARD_SIZE + 3 - to_x;
else
to_y = BOARD_SIZE - 1 - to_y;
if ((fromX == to_x) && (fromY == to_y)) {
fromX = fromY = -1;
return;
}
if (gameMode == EditPosition) {
ChessSquare piece;
if ( off_board(fromX) ) {
/* Remove a catched piece */
int c = ((fromX < 5) ^ flipView);
int i = PieceOfCatched(c,fromX,fromY,0);
if ( i == no_piece ) {
fromX = fromY = -1;
return;
} else {
piece = catchedIndexToPiece[c][i];
catches[0][c][i]--;
UpdateCatched(c, i, False, False, 0);
}
} else {
/* remove piece from board field */
fromX -= 2;
piece = boards[0][fromY][fromX];
boards[0][fromY][fromX] = EmptySquare;
DrawSquare(fromY, fromX, EmptySquare);
}
if ( !off_board(to_x) ) {
/* drop piece to board field */
ChessSquare catched_piece;
to_x -= 2;
catched_piece = boards[0][to_y][to_x];
if ( catched_piece != EmptySquare ) {
/* put piece to catched pieces */
int i = pieceToCatchedIndex[catched_piece];
int c = (catched_piece < WhitePawn );
catches[0][c][i]++;
UpdateCatched(c, i, True, False, 0);
};
/* place moved piece */
boards[0][to_y][to_x] = piece;
DrawSquare(to_y, to_x, piece);
}
fromX = fromY = -1;
XSync(xDisplay, False);
return;
}
if ( off_board(fromX) ) {
int c = BLACK_ON_MOVE ? 0 : 1;
int piece = PieceOfCatched(c,fromX,fromY,currentMove);
if ( piece == no_piece ) {
fromX = fromY = -1;
return;
} else {
fromX = fromY = piece + 81;
to_x -= 2;
move_type = BLACK_ON_MOVE ? BlackDrop : WhiteDrop;
MakeMove(&move_type, fromX, fromY, to_x, to_y);
FinishUserMove(move_type, to_x, to_y);
break;
};
} else if ( off_board(to_x) ) {
fromX = fromY = -1;
return;
} else {
fromX -= 2; to_x -= 2;
from_piece = boards[currentMove][fromY][fromX];
if ( PromotionPossible(fromY, to_y, from_piece) ) {
PromotionPopUp(from_piece, to_x, to_y);
return;
}
move_type = NormalMove;
MakeMove(&move_type, fromX, fromY, to_x, to_y);
FinishUserMove(move_type, to_x, to_y);
break;
}
}
}
void
FinishUserMove(move_type, to_x, to_y)
ChessMove move_type;
int to_x, to_y;
{
char user_move[MSG_SIZ];
switch (move_type) {
default:
fprintf(stderr, "%s: internal error; bad move_type\n",
programName);
break;
case BlackPromotion:
case WhitePromotion:
sprintf(user_move, "%c%c%c%c+\n",
'9' - fromX, 'i' - fromY, '9' - to_x, 'i' - to_y);
break;
case BlackDrop:
case WhiteDrop:
sprintf(user_move, "%c*%c%c\n",
catchedIndexToChar[fromX - 81],'9' - to_x, 'i' - to_y);
break;
case NormalMove:
sprintf(user_move, "%c%c%c%c\n",
'9' - fromX, 'i' - fromY, '9' - to_x, 'i' - to_y);
break;
}
fromX = fromY = -1;
Attention(firstProgramPID);
SendToProgram(user_move, toFirstProgFP);
strcpy(moveList[currentMove - 1], user_move);
if (gameMode == PauseGame)
PauseProc(); /* a user move restarts a paused game*/
switch (gameMode) {
case ForceMoves:
case SetupPosition:
break;
case BeginningOfGame:
if (appData.noChessProgram)
lastGameMode = gameMode = ForceMoves;
else
lastGameMode = gameMode = MachinePlaysWhite;
ModeHighlight();
break;
case MachinePlaysWhite:
case MachinePlaysBlack:
default:
break;
}
}
/* Simple parser for moves from gnuchess. */
void
ParseMachineMove(machine_move, move_type, from_x, from_y, to_x, to_y)
char *machine_move;
ChessMove *move_type;
int *from_x, *from_y, *to_x, *to_y;
{
#define no_digit(c) (c < '0' || c > '9' )
{
if ( no_digit(machine_move[0]) ) {
switch ( machine_move[0] ) {
case 'P': *from_x = 81; break;
case 'L': *from_x = 82; break;
case 'N': *from_x = 83; break;
case 'S': *from_x = 84; break;
case 'G': *from_x = 85; break;
case 'B': *from_x = 86; break;
case 'R': *from_x = 87; break;
case 'K': *from_x = 88; break;
default: *from_x = -1;
};
*from_y = *from_x;
*to_x = '9' - machine_move[2];
*to_y = 'i' - machine_move[3];
} else {
*from_x = '9' - machine_move[0] ;
*from_y = 'i' - machine_move[1];
*to_x = '9' - machine_move[2];
*to_y = 'i' - machine_move[3];
switch (machine_move[4]) {
case '+':
*move_type = BLACK_ON_MOVE ?
BlackPromotion : WhitePromotion;
break;
default:
*move_type = NormalMove;
break;
}
}
}
}
void
HandleMachineMove(message, fp)
char *message;
FILE *fp;
{
char machine_move[MSG_SIZ], buf1[MSG_SIZ], buf2[MSG_SIZ];
int i, j, from_x, from_y, to_x, to_y;
ChessMove move_type;
maybeThinking = False;
if (strncmp(message, "warning:", 8) == 0) {
DisplayMessage(message);
return;
}
/*
* If chess program startup fails, exit with an error message.
* Attempts to recover here are futile.
*/
if ((StrStr(message, "unknown host") != NULL)
|| (StrStr(message, "No remote directory") != NULL)
|| (StrStr(message, "not found") != NULL)
|| (StrStr(message, "No such file") != NULL)
|| (StrStr(message, "Permission denied") != NULL)) {
fprintf(stderr,
"%s: failed to start chess program %s on %s: %s\n",
programName,
fp == fromFirstProgFP ? appData.firstChessProgram
: appData.secondChessProgram,
fp == fromFirstProgFP ? appData.firstHost
: appData.secondHost,
message);
ShutdownChessPrograms(message);
exit(1);
}
/*
* If the move is illegal, cancel it and redraw the board.
*/
if (strncmp(message, "Illegal move", 12) == 0) {
if (currentMove <= (whitePlaysFirst ? 1 : 0)) return;
if (gameMode == PlayFromGameFile) {
/* Stop reading this game file */
gameMode = ForceMoves;
ModeHighlight();
}
currentMove--;
if ((gameMode == PlayFromGameFile) ||
(gameMode == ForceMoves) ||
(gameMode == SetupPosition))
DisplayClocks(ReDisplayTimers);
else
DisplayClocks(SwitchTimers);
sprintf(buf1, "Illegal move: %s", parseList[currentMove]);
DisplayMessage(buf1);
/*
* Only redraw the squares that have changed.
*/
for (i = 0; i < BOARD_SIZE; i++)
for (j = 0; j < BOARD_SIZE; j++) {
if (boards[currentMove][i][j] !=
boards[currentMove + 1][i][j])
DrawSquare(i, j, boards[currentMove][i][j]);
}
UpdateCatched(0,0,False,True, currentMove);
UpdateCatched(1,0,False,True, currentMove);
XSync(xDisplay, False);
return;
}
if (strncmp(message, "Hint:", 5) == 0) {
sscanf(message, "Hint: %s", machine_move);
ParseMachineMove(machine_move, &move_type,
&from_x, &from_y, &to_x, &to_y);
if ( move_type == WhitePromotion || move_type == BlackPromotion )
move_type = MakeAlg(from_x, from_y, to_x, to_y, '+',
currentMove, buf1);
else
move_type = MakeAlg(from_x, from_y, to_x, to_y, '\000',
currentMove, buf1);
sprintf(buf2, "Hint: %s", buf1);
DisplayMessage(buf2);
return;
}
/*
* win, lose or draw
*/
if (strncmp(message, "Black", 5) == 0) {
ShutdownChessPrograms("Black wins");
return;
} else if (strncmp(message, "White", 5) == 0) {
ShutdownChessPrograms("White wins");
return;
} else if (strncmp(message, "opponent mates!", 15) == 0) {
switch (gameMode) {
case MachinePlaysWhite:
ShutdownChessPrograms("Black wins");
break;
case MachinePlaysBlack:
ShutdownChessPrograms("White wins");
break;
case TwoMachinesPlay:
ShutdownChessPrograms(fp == fromFirstProgFP ?
"Black wins" : "White wins");
break;
default:
/* can't happen */
break;
}
return;
} else if (strncmp(message, "computer mates!", 15) == 0) {
switch (gameMode) {
case MachinePlaysWhite:
ShutdownChessPrograms("White wins");
break;
case MachinePlaysBlack:
ShutdownChessPrograms("Black wins");
break;
case TwoMachinesPlay:
ShutdownChessPrograms(fp == fromFirstProgFP ?
"White wins" : "Black wins");
break;
default:
/* can't happen */
break;
}
return;
} else if (strncmp(message, "Draw", 4) == 0) {
ShutdownChessPrograms("Draw");
return;
}
/*
* normal machine reply move
*/
maybeThinking = True;
if (StrStr(message, "...") != NULL) {
sscanf(message, "%s %s %s", buf1, buf2, machine_move);
if (machine_move[0] == '\0')
return;
} else
return; /* ignore noise */
strcpy(moveList[currentMove], machine_move);
ParseMachineMove(machine_move, &move_type, &from_x, &from_y,
&to_x, &to_y);
MakeMove(&move_type, from_x, from_y, to_x, to_y);
#if BLINK_COUNT
if ( gameMode != TwoMachinesPlay )
BlinkSquare(to_y, to_x, boards[currentMove][to_y][to_x]);
#endif
switch (gameMode) {
case PauseGame:
case EndOfGame:
default:
break;
case ForceMoves:
case SetupPosition:
case PlayFromGameFile:
strncat(machine_move, "\n", 1);
SendToProgram(machine_move, toFirstProgFP);
break;
case TwoMachinesPlay:
strncat(machine_move, "\n", 1);
if (BLACK_ON_MOVE) {
Attention(secondProgramPID);
SendToProgram(machine_move, toSecondProgFP);
if (firstMove) {
firstMove = False;
SendToProgram(appData.blackString,
toSecondProgFP);
}
} else {
Attention(firstProgramPID);
SendToProgram(machine_move, toFirstProgFP);
if (firstMove) {
firstMove = False;
SendToProgram(appData.whiteString,
toFirstProgFP);
}
}
break;
}
}
#if BLINK_COUNT
static int BlinkCount;
static int BlinkRow, BlinkCol;
static ChessSquare BlinkPiece;
void
BlinkSquareProc ()
{
if ( BlinkCount-- ) {
DrawSquare (BlinkRow,BlinkCol,
(BlinkCount & 1) ? EmptySquare : BlinkPiece);
blinkSquareXID = XtAppAddTimeOut(appContext,
(int) (150),
(XtTimerCallbackProc) BlinkSquareProc, NULL);
}
}
void
BlinkSquare (row, col, piece)
int row, col;
ChessSquare piece;
{
BlinkCount = 2*BLINK_COUNT + 1;
BlinkRow = row;
BlinkCol = col;
BlinkPiece = piece;
BlinkSquareProc();
}
#endif /* BLINK_COUNT */
void
ReadGameFile()
{
for (;;) {
if (!ReadGameFileProc())
return;
if (matchMode == MatchOpening)
continue;
readGameXID = XtAppAddTimeOut(appContext,
(int) (1000 * appData.timeDelay),
(XtTimerCallbackProc) ReadGameFile, NULL);
break;
}
}
int
ReadGameFileProc()
{
int from_x, from_y, to_x, to_y, done;
ChessMove move_type;
char move[MSG_SIZ];
if (gameFileFP == NULL)
return (int) False;
if (gameMode == PauseGame) return True;
if (gameMode != PlayFromGameFile) {
fclose(gameFileFP);
gameFileFP = NULL;
return (int) False;
}
if (commentUp) {
XtPopdown(commentShell);
XtDestroyWidget(commentShell);
commentUp = False;
}
parseGameFile ();
move_type = (ChessMove) 0;
lastGameMode = gameMode;
gameMode = ForceMoves;
ModeHighlight();
DisplayMessage("End of game file");
if (readGameXID != 0) {
XtRemoveTimeOut(readGameXID);
readGameXID = 0;
}
fclose(gameFileFP);
gameFileFP = NULL;
return ((int) False);
}
/*
* MakeMove() displays moves. If they are illegal, GNU shogi will detect
* this and send an Illegal move message. XShogi will then retract the move.
* The clockMode False case is tricky because it displays the player on move.
*/
void
MakeMove(move_type, from_x, from_y, to_x, to_y)
ChessMove *move_type;
int from_x, from_y, to_x, to_y;
{
char message[MSG_SIZ], movestr[MSG_SIZ];
char pieceChar = '\000';
ChessSquare piece;
CopyBoard(boards[currentMove + 1], boards[currentMove]);
CopyCatches(catches[currentMove + 1], catches[currentMove]);
forwardMostMove = ++currentMove;
if ((gameMode == PlayFromGameFile) || (gameMode == ForceMoves) ||
(gameMode == SetupPosition))
DisplayClocks(ReDisplayTimers);
else
DisplayClocks(SwitchTimers);
if ( from_x > 80 ) {
int i = from_x - 81, c = (BLACK_ON_MOVE ? 1 : 0);
ChessSquare cpiece = catchedIndexToPiece[c][i];
boards[currentMove][to_y][to_x] = cpiece;
DrawSquare(to_y, to_x, cpiece);
catches[currentMove][c][i]--;
UpdateCatched(c, i, False, False, currentMove);
} else if (PromotionPossible(from_y,to_y,piece = boards[currentMove][from_y][from_x])) {
ChessSquare cpiece = boards[currentMove][to_y][to_x];
if ( cpiece != EmptySquare ) {
int i = pieceToCatchedIndex[cpiece];
int c = (cpiece < WhitePawn );
catches[currentMove][c][i]++;
UpdateCatched(c, i, True, False, currentMove);
};
if ( *move_type == NormalMove ) {
boards[currentMove][to_y][to_x] = piece;
} else {
boards[currentMove][to_y][to_x] = piece = pieceToPromoted[piece];
pieceChar = '+';
}
boards[currentMove][from_y][from_x] = EmptySquare;
DrawSquare(from_y, from_x, boards[currentMove][from_y][from_x]);
DrawSquare(to_y, to_x, boards[currentMove][to_y][to_x]);
} else {
ChessSquare piece = boards[currentMove][to_y][to_x];
if ( piece != EmptySquare ) {
int i = pieceToCatchedIndex[piece];
int c = (piece < WhitePawn );
catches[currentMove][c][i]++;
UpdateCatched(c, i, True, False, currentMove);
};
*move_type = NormalMove;
boards[currentMove][to_y][to_x] =
boards[currentMove][from_y][from_x];
boards[currentMove][from_y][from_x] = EmptySquare;
DrawSquare(to_y, to_x, boards[currentMove][to_y][to_x]);
DrawSquare(from_y, from_x,
boards[currentMove][from_y][from_x]);
}
if (gameMode == PlayFromGameFile) {
sprintf(message, "%d. %s%s", (currentMove + 1) / 2,
BLACK_ON_MOVE ? "... " : "", currentMoveString);
strcpy(parseList[currentMove - 1], currentMoveString);
} else {
MakeAlg(from_x, from_y, to_x, to_y, pieceChar,
currentMove - 1, movestr);
sprintf(message, "%d. %s%s", (currentMove + 1) / 2,
BLACK_ON_MOVE ? "... " : "", movestr);
strcpy(parseList[currentMove - 1], movestr);
}
DisplayMessage(message);
XSync(xDisplay, False);
}
void
InitChessProgram(host_name, program_name, pid, to, from, xid)
char *host_name, *program_name;
int *pid;
FILE **to, **from;
XtIntervalId *xid;
{
char arg_buf[10];
char *arg1, *arg2;
int to_prog[2], from_prog[2];
FILE *from_fp, *to_fp;
int dummy_source;
XtInputId dummy_id;
#if SYSTEM_FIVE || SYSV
char *pty_name;
#endif
if (appData.noChessProgram) return;
#if SYSTEM_FIVE || SYSV
if ((pty_name = PseudoTTY(&to_prog[1])) == NULL) {
fprintf(stderr, "%s: can't open pseudo-tty\n", programName);
perror("");
exit(1);
}
from_prog[0] = to_prog[1];
to_prog[0] = from_prog[1] = open(pty_name, O_RDWR, 0);
#if SVR4
if (ioctl (to_prog[0], I_PUSH, "ptem") == -1 ||
ioctl (to_prog[0], I_PUSH, "ldterm") == -1 ||
ioctl (to_prog[0], I_PUSH, "ttcompat") == -1) {
fprintf(stderr, "%s: can't ioctl pseudo-tty\n", programName);
perror("");
exit(1);
}
#endif
#else
signal(SIGPIPE, CatchPipeSignal);
pipe(to_prog);
pipe(from_prog);
#endif
if ((*pid = fork()) == 0) {
#if !SYSTEM_FIVE && !SYSV
signal(SIGPIPE, CatchPipeSignal);
#endif
dup2(to_prog[0], 0);
dup2(from_prog[1], 1);
close(to_prog[0]);
close(to_prog[1]);
close(from_prog[0]);
close(from_prog[1]);
dup2(1, fileno(stderr)); /* force stderr to the pipe */
if (appData.searchTime != NULL) {
sprintf(arg_buf, "%d", searchTime);
arg1 = arg_buf;
arg2 = (char *) NULL;
} else if (appData.searchDepth > 0) {
sprintf(arg_buf, "%d", appData.searchDepth);
arg1 = "1";
arg2 = "9999";
} else {
sprintf(arg_buf, "%d", appData.movesPerSession);
arg1 = arg_buf;
arg2 = appData.timeControl;
}
if (strcmp(host_name, "localhost") == 0) {
execlp(program_name, program_name, arg1, arg2,
(char *) NULL);
} else {
execlp(appData.remoteShell, appData.remoteShell,
host_name, program_name, arg1, arg2,
(char *) NULL);
}
perror(program_name);
exit(1);
}
close(to_prog[0]);
close(from_prog[1]);
*from = from_fp = fdopen(from_prog[0], "r");
*to = to_fp = fdopen(to_prog[1], "w");
setbuf(from_fp, NULL); setbuf(to_fp, NULL);
ReceiveFromProgram(from_fp, &dummy_source, &dummy_id); /*"Chess"*/
if (*pid == 0) return;
*xid = XtAppAddInput(appContext, fileno(from_fp),
(XtPointer)XtInputReadMask,
(XtInputCallbackProc)ReceiveFromProgram,
(XtPointer)from_fp);
SendToProgram(appData.initString, *to);
SendSearchDepth(*to);
}
void
ShutdownChessPrograms(why)
char *why;
{
lastGameMode = gameMode;
gameMode = EndOfGame;
ModeHighlight();
CopyBoard(boards[currentMove + 1], boards[currentMove]);
CopyCatches(catches[currentMove + 1], catches[currentMove]);
strncpy(parseList[currentMove], why, MOVE_LEN);
parseList[currentMove][MOVE_LEN-1] = '\000';
currentMove++;
DisplayMessage(why);
if (readGameXID != 0)
XtRemoveTimeOut(readGameXID);
readGameXID = 0;
if (firstProgramPID != 0) {
fclose(fromFirstProgFP);
fclose(toFirstProgFP);
fromFirstProgFP = toFirstProgFP = NULL;
if (kill(firstProgramPID, SIGTERM)==0)
wait((union wait *)0);
}
firstProgramPID = 0;
if (firstProgramXID != 0)
XtRemoveInput(firstProgramXID);
firstProgramXID = 0;
if (secondProgramPID != 0) {
fclose(fromSecondProgFP);
fclose(toSecondProgFP);
fromSecondProgFP = toSecondProgFP = NULL;
if (kill(secondProgramPID, SIGTERM)==0)
wait((union wait *)0);
}
secondProgramPID = 0;
if (secondProgramXID != 0)
XtRemoveInput(secondProgramXID);
secondProgramXID = 0;
DisplayClocks(StopTimers);
if(matchMode != MatchFalse) {
if (appData.saveGameFile[0] != '\0')
SaveGameProc(appData.saveGameFile);
exit(0);
}
}
void
CommentPopUp(label)
char *label;
{
Arg args[2];
Position x, y;
Dimension bw_width, pw_width;
if (commentUp) {
XtPopdown(commentShell);
XtDestroyWidget(commentShell);
commentUp = False;
}
DisplayMessage("Comment");
XtSetArg(args[0], XtNwidth, &bw_width);
XtGetValues(formWidget, args, 1);
XtSetArg(args[0], XtNresizable, True);
XtSetArg(args[1], XtNwidth, bw_width - 8);
commentShell = XtCreatePopupShell("Comment",
transientShellWidgetClass, commandsWidget, args, 2);
XtSetArg(args[0], XtNlabel, label);
(void) XtCreateManagedWidget("commentLabel", labelWidgetClass,
commentShell, args, 1);
XtRealizeWidget(commentShell);
XtSetArg(args[0], XtNwidth, &pw_width);
XtGetValues(commentShell, args, 1);
XtTranslateCoords(shellWidget, (bw_width - pw_width) / 2, -50, &x, &y);
XtSetArg(args[0], XtNx, x);
XtSetArg(args[1], XtNy, y);
XtSetValues(commentShell, args, 2);
XtPopup(commentShell, XtGrabNone);
commentUp = True;
}
void
FileNamePopUp(label, proc)
char *label;
void (*proc) P((char *name));
{
Arg args[2];
Widget popup, dialog;
Position x, y;
Dimension bw_width, pw_width;
fileProc = proc;
XtSetArg(args[0], XtNwidth, &bw_width);
XtGetValues(boardWidget, args, 1);
XtSetArg(args[0], XtNresizable, True);
XtSetArg(args[1], XtNwidth, DIALOG_SIZE);
popup = XtCreatePopupShell("File Name Prompt",
transientShellWidgetClass, commandsWidget, args, 2);
XtSetArg(args[0], XtNlabel, label);
XtSetArg(args[1], XtNvalue, "");
dialog = XtCreateManagedWidget("dialog", dialogWidgetClass,
popup, args, 2);
XawDialogAddButton(dialog, "ok", FileNameCallback, (XtPointer) dialog);
XawDialogAddButton(dialog, "cancel", FileNameCallback,
(XtPointer) dialog);
XtRealizeWidget(popup);
XtSetArg(args[0], XtNwidth, &pw_width);
XtGetValues(popup, args, 1);
XtTranslateCoords(boardWidget, (bw_width - pw_width) / 2, 10, &x, &y);
XtSetArg(args[0], XtNx, x);
XtSetArg(args[1], XtNy, y);
XtSetValues(popup, args, 2);
XtPopup(popup, XtGrabExclusive);
filenameUp = True;
XtSetKeyboardFocus(shellWidget, popup);
}
void
FileNameCallback(w, client_data, call_data)
Widget w;
XtPointer client_data, call_data;
{
String name;
Arg args[1];
XtSetArg(args[0], XtNlabel, &name);
XtGetValues(w, args, 1);
if (strcmp(name, "cancel") == 0) {
XtPopdown(w = XtParent(XtParent(w)));
XtDestroyWidget(w);
filenameUp = False;
ModeHighlight();
return;
}
FileNameAction(w, NULL);
}
void
FileNameAction(w, event)
Widget w;
XEvent *event;
{
char buf[MSG_SIZ];
String name;
name = XawDialogGetValueString(w = XtParent(w));
if ((name != NULL) && (*name != '\0')) {
strcpy(buf, name);
XtPopdown(w = XtParent(w));
XtDestroyWidget(w);
filenameUp = False;
(*fileProc)(buf); /* I can't see a way not
to use a global here */
ModeHighlight();
return;
}
XtPopdown(w = XtParent(w));
XtDestroyWidget(w);
filenameUp = False;
ModeHighlight();
}
typedef struct {
ChessSquare piece;
int to_x, to_y;
} PromotionMoveInfo;
static PromotionMoveInfo pmi; /*making this global is gross */
void
PromotionPopUp(piece, to_x, to_y)
ChessSquare piece;
int to_x, to_y;
{
Arg args[2];
Widget dialog;
Position x, y;
Dimension bw_width, bw_height, pw_width, pw_height;
pmi.piece = piece;
pmi.to_x = to_x;
pmi.to_y = to_y;
XtSetArg(args[0], XtNwidth, &bw_width);
XtSetArg(args[1], XtNheight, &bw_height);
XtGetValues(boardWidget, args, 2);
XtSetArg(args[0], XtNresizable, True);
promotionShell = XtCreatePopupShell("Promotion",
transientShellWidgetClass, commandsWidget, args, 1);
XtSetArg(args[0], XtNlabel, "Promote piece?");
dialog = XtCreateManagedWidget("promotion", dialogWidgetClass,
promotionShell, args, 1);
XawDialogAddButton(dialog, "Yes", PromotionCallback,
(XtPointer) dialog);
XawDialogAddButton(dialog, "No", PromotionCallback,
(XtPointer) dialog);
XawDialogAddButton(dialog, "cancel", PromotionCallback,
(XtPointer) dialog);
XtRealizeWidget(promotionShell);
XtSetArg(args[0], XtNwidth, &pw_width);
XtSetArg(args[1], XtNheight, &pw_height);
XtGetValues(promotionShell, args, 2);
XtTranslateCoords(boardWidget, (bw_width - pw_width) / 2,
LINE_GAP + squareSize/3 +
((piece == BlackPawn) ^ (flipView) ?
0 : 6*(squareSize + LINE_GAP)),
&x, &y);
XtSetArg(args[0], XtNx, x);
XtSetArg(args[1], XtNy, y);
XtSetValues(promotionShell, args, 2);
XtPopup(promotionShell, XtGrabNone);
promotionUp = True;
}
void
PromotionCallback(w, client_data, call_data)
Widget w;
XtPointer client_data, call_data;
{
String name;
Arg args[1];
ChessMove move_type;
XtSetArg(args[0], XtNlabel, &name);
XtGetValues(w, args, 1);
XtPopdown(w = XtParent(XtParent(w)));
XtDestroyWidget(w);
promotionUp = False;
if (fromX == -1) return;
if (strcmp(name, "Yes") == 0) {
if ((int) pmi.piece < (int) WhitePawn)
move_type = BlackPromotion;
else
move_type = WhitePromotion;
} else if (strcmp(name, "No") == 0) {
move_type = NormalMove;
} else /* strcmp(name, "cancel") == 0 */ {
fromX = fromY = -1;
return;
}
MakeMove(&move_type, fromX, fromY, pmi.to_x, pmi.to_y);
FinishUserMove(move_type, pmi.to_x, pmi.to_y);
}
typedef struct {
char mode[2];
char name[100];
} FileModeInfo;
static FileModeInfo fmi;
void
FileModePopUp (name)
char *name;
{
Arg args[2];
Widget dialog;
Position x, y;
Dimension bw_width, bw_height, pw_width, pw_height;
strcpy(fmi.name,name);
XtSetArg(args[0], XtNwidth, &bw_width);
XtSetArg(args[1], XtNheight, &bw_height);
XtGetValues(boardWidget, args, 2);
XtSetArg(args[0], XtNresizable, True);
filemodeShell = XtCreatePopupShell("FileMode",
transientShellWidgetClass, commandsWidget, args, 1);
XtSetArg(args[0], XtNlabel, "Append to existing file?");
dialog = XtCreateManagedWidget("filemode", dialogWidgetClass,
filemodeShell, args, 1);
XawDialogAddButton(dialog, "Yes", FileModeCallback,
(XtPointer) dialog);
XawDialogAddButton(dialog, "No", FileModeCallback,
(XtPointer) dialog);
XawDialogAddButton(dialog, "cancel", FileModeCallback,
(XtPointer) dialog);
XtRealizeWidget(filemodeShell);
XtSetArg(args[0], XtNwidth, &pw_width);
XtSetArg(args[1], XtNheight, &pw_height);
XtGetValues(filemodeShell, args, 2);
XtTranslateCoords(boardWidget, (bw_width - pw_width) / 2,
LINE_GAP + squareSize/3 +
(6*(squareSize + LINE_GAP)),
&x, &y);
XtSetArg(args[0], XtNx, x);
XtSetArg(args[1], XtNy, y);
XtSetValues(filemodeShell, args, 2);
XtPopup(filemodeShell, XtGrabNone);
filemodeUp = True;
}
void
FileModeCallback(w, client_data, call_data)
Widget w;
XtPointer client_data, call_data;
{
String name;
Arg args[1];
XtSetArg(args[0], XtNlabel, &name);
XtGetValues(w, args, 1);
XtPopdown(w = XtParent(XtParent(w)));
XtDestroyWidget(w);
if (strcmp(name, "Yes") == 0) {
strcpy(fmi.mode,"a");
} else if (strcmp(name, "No") == 0) {
strcpy(fmi.mode,"w");
} else /* strcmp(name, "cancel") == 0 */ {
filemodeUp = False;
return;
}
XtPopdown(filemodeShell);
XtDestroyWidget(filemodeShell);
SaveGameProc(fmi.name);
filemodeUp = False;
}
void
SelectCommand(w, client_data, call_data)
Widget w;
XtPointer client_data, call_data;
{
XawListReturnStruct *list_return = XawListShowCurrent(w);
fromX = fromY = -1;
if (promotionUp) {
XtPopdown(promotionShell);
XtDestroyWidget(promotionShell);
promotionUp = False;
}
if ((gameMode == PauseGame)
&& (list_return->list_index != (int) ButtonPause))
PauseProc();
switch ((Button) list_return->list_index) {
case ButtonQuit:
QuitProc();
break;
case ButtonBackward:
BackwardProc();
break;
case ButtonForward:
ForwardProc();
break;
case ButtonFlipView:
FlipProc();
break;
case ButtonReset:
ResetFileProc();
ResetProc();
break;
case ButtonSaveGame:
if (appData.saveGameFile[0] == '\0')
FileNamePopUp("Filename for saved game?",
SaveGameProc);
else
SaveGameProc(appData.saveGameFile);
break;
case ButtonSavePosition:
if (appData.savePositionFile[0] == '\0')
FileNamePopUp("Filename for saved position?",
SavePositionProc);
else
SavePositionProc(appData.savePositionFile);
break;
case ButtonHint:
HintProc();
break;
#ifdef notdef
case ButtonSwitchSides:
SwitchProc();
break;
#endif /*notdef*/
case ButtonEditPosition:
EditPositionProc();
break;
case ButtonLoadPosition:
if (gameMode != BeginningOfGame) {
DisplayMessage("Press Reset first");
break;
}
if (appData.loadPositionFile == NULL)
FileNamePopUp("Position file name?",
VOID_PROC SetupPositionFromFileProc);
else
(void) SetupPositionFromFileProc(
appData.loadPositionFile);
break;
case ButtonLoadGame:
GameProc();
break;
case ButtonMachineWhite:
MachinePlaysWhiteProc();
break;
case ButtonMachineBlack:
MachinePlaysBlackProc();
break;
case ButtonTwoMachines:
TwoMachinesPlayProc();
break;
case ButtonForceMoves:
ForceProc();
break;
case ButtonPause:
PauseProc();
break;
}
if (!filenameUp) ModeHighlight();
}
void
ModeHighlight()
{
switch (gameMode) {
case BeginningOfGame:
if (appData.noChessProgram)
XawListHighlight(commandsWidget, ButtonForceMoves);
else
XawListHighlight(commandsWidget, ButtonMachineWhite);
break;
case MachinePlaysWhite:
XawListHighlight(commandsWidget, ButtonMachineWhite);
break;
case MachinePlaysBlack:
XawListHighlight(commandsWidget, ButtonMachineBlack);
break;
case TwoMachinesPlay:
XawListHighlight(commandsWidget, ButtonTwoMachines);
break;
case ForceMoves:
case SetupPosition:
XawListHighlight(commandsWidget, ButtonForceMoves);
break;
case PlayFromGameFile:
XawListHighlight(commandsWidget, ButtonLoadGame);
break;
case PauseGame:
XawListHighlight(commandsWidget, ButtonPause);
break;
case EditPosition:
XawListHighlight(commandsWidget, ButtonEditPosition);
break;
case EndOfGame:
default:
XawListUnhighlight(commandsWidget);
break;
}
}
/*
* Button procedures
*/
void
QuitProc()
{
ShutdownChessPrograms("Quitting");
exit(0);
}
int
PlayFromGameFileProc(name)
char *name;
{
char buf[MSG_SIZ];
ChessMove cm;
if (gameMode != BeginningOfGame) {
DisplayMessage("Press Reset first");
return (int) False;
}
if (appData.loadGameFile != name) {
if (appData.loadGameFile)
XtFree(appData.loadGameFile);
appData.loadGameFile = XtMalloc(strlen(name)+1);
strcpy(appData.loadGameFile, name);
}
if ((gameFileFP = fopen(name, "r")) == NULL) {
sprintf(buf, "Can't open %s", name);
DisplayMessage(buf);
XtFree(appData.loadGameFile);
appData.loadGameFile = NULL;
return (int) False;
}
lastGameMode = gameMode = PlayFromGameFile;
ModeHighlight();
InitPosition();
DisplayClocks(StopTimers);
if (firstProgramXID == 0)
InitChessProgram(appData.firstHost, appData.firstChessProgram,
&firstProgramPID, &toFirstProgFP,
&fromFirstProgFP, &firstProgramXID);
SendToProgram(appData.initString, toFirstProgFP);
SendSearchDepth(toFirstProgFP);
SendToProgram("force\n", toFirstProgFP);
ReadGameFile();
return (int) True;
}
void
ResurrectChessProgram()
/* Restart the chess program and feed it all the moves made so far.
Used when the user wants to back up from end of game, when gnuchess
has already exited. Assumes gameMode == EndOfGame. */
{
char buf[MSG_SIZ];
int i;
if (currentMove > 0)
currentMove--; /* delete "Black wins" or the like */
InitChessProgram(appData.firstHost, appData.firstChessProgram,
&firstProgramPID, &toFirstProgFP, &fromFirstProgFP,
&firstProgramXID);
SendToProgram(appData.initString, toFirstProgFP);
SendSearchDepth(toFirstProgFP);
SendToProgram("force\n", toFirstProgFP);
gameMode = lastGameMode = ForceMoves;
ModeHighlight();
i = whitePlaysFirst ? 1 : 0;
if (startedFromSetupPosition) {
SendBoard(toFirstProgFP, boards[i], catches[i]);
}
for (; i < currentMove; i++) {
strcpy(buf, moveList[i]);
SendToProgram(buf, toFirstProgFP);
}
DisplayClocks(ResetTimers);
/* ugh, but there's no way to tell gnuchess what the clocks
should read, so the best we can do is bow to its notion.
!!gnuchess 4.0 adds a feature that will let us fix this. */
}
void
MachinePlaysWhiteProc()
{
if (gameMode == EditPosition) EditPositionDone();
if ((gameMode == EndOfGame) || (gameMode == PlayFromGameFile)
|| (gameMode == TwoMachinesPlay) || appData.noChessProgram
|| (gameMode == MachinePlaysWhite))
return;
if (BLACK_ON_MOVE) {
DisplayMessage("It is not White's turn");
return;
}
lastGameMode = gameMode = MachinePlaysWhite;
ModeHighlight();
SendToProgram(appData.whiteString, toFirstProgFP);
DisplayClocks(StartTimers);
}
void
ForwardProc()
{
char buf[MSG_SIZ];
int i, j;
if (gameMode == BeginningOfGame) {
if (currentMove != 0)
return;
if (appData.loadGameFile != NULL) {
if (PlayFromGameFileProc(appData.loadGameFile)) {
XtRemoveTimeOut(readGameXID);
readGameXID = 0;
}
}
return;
}
if ((gameMode == EndOfGame) || (gameMode == TwoMachinesPlay)
|| (gameMode == EditPosition)
|| ((currentMove == 0) && (forwardMostMove == 0)))
return;
if ((gameMode != PlayFromGameFile) && (currentMove >= forwardMostMove))
return;
if (gameMode != PauseGame) {
PauseProc();
if (readGameXID != 0) {
XtRemoveTimeOut(readGameXID);
readGameXID = 0;
}
}
if (currentMove >= forwardMostMove) {
ReadGameFileProc();
return;
}
if ((gameMode != ForceMoves) && (gameMode != PlayFromGameFile) &&
(gameMode != SetupPosition)) {
lastGameMode = gameMode = ForceMoves;
ModeHighlight();
SendToProgram("force\n", toFirstProgFP);
DisplayClocks(StopTimers);
}
for (i = 0; i < BOARD_SIZE; i++)
for (j = 0; j < BOARD_SIZE; j++)
if (boards[currentMove + 1][i][j] != boards[currentMove][i][j])
DrawSquare(i, j, boards[currentMove + 1][i][j]);
UpdateCatched(0,0,False,True,currentMove+1);
UpdateCatched(1,0,False,True,currentMove+1);
sprintf(buf, "%d. %s%s", (currentMove / 2) + 1,
BLACK_ON_MOVE ? "... " : "", parseList[currentMove]);
DisplayMessage(buf);
strcpy(buf, moveList[currentMove++]);
SendToProgram(buf, toFirstProgFP);
DisplayClocks(ReDisplayTimers);
}
void
ResetFileProc()
{
char *buf = "";
if (appData.loadGameFile);
XtFree(appData.loadGameFile);
if (appData.loadPositionFile);
XtFree(appData.loadPositionFile);
appData.loadGameFile = appData.loadPositionFile = NULL;
DisplayName(buf);
if (gameFileFP != NULL) {
fclose(gameFileFP);
gameFileFP = NULL;
}
}
void
ResetProc()
{
flipView = False;
startedFromSetupPosition = whitePlaysFirst = False;
matchMode = MatchFalse;
firstMove = True;
blackFlag = whiteFlag = False;
maybeThinking = False;
ShutdownChessPrograms("");
lastGameMode = gameMode = BeginningOfGame;
ModeHighlight();
InitPosition();
InitChessProgram(appData.firstHost, appData.firstChessProgram,
&firstProgramPID, &toFirstProgFP,
&fromFirstProgFP, &firstProgramXID);
DisplayClocks(ResetTimers);
if (commentUp) {
XtPopdown(commentShell);
XtDestroyWidget(commentShell);
commentUp = False;
}
if (promotionUp) {
XtPopdown(promotionShell);
XtDestroyWidget(promotionShell);
promotionUp = False;
}
}
static
void
ClearCatches (catches)
Catched catches;
{
int c, p;
for ( c = 0; c <= 1; c++)
for ( p = 0; p <= 7; p++ )
catches[c][p] = 0;
}
int
SetupPositionFromFileProc(name)
char *name;
{
char *p, line[MSG_SIZ], buf[MSG_SIZ];
Board initial_position;
Catched initial_catches;
FILE *fp;
int i, j;
if (gameMode != BeginningOfGame) {
DisplayMessage("Press Reset first");
return (int) False;
}
if (appData.loadPositionFile != name) {
if (appData.loadPositionFile)
XtFree(appData.loadPositionFile);
appData.loadPositionFile = XtMalloc(strlen(name)+1);
strcpy(appData.loadPositionFile, name);
}
if ((fp = fopen(name, "r")) == NULL) {
sprintf(buf, "Can't open %s", name);
DisplayMessage(buf);
XtFree(appData.loadPositionFile);
appData.loadPositionFile = NULL;
return (int) False;
}
lastGameMode = gameMode = SetupPosition;
ModeHighlight();
startedFromSetupPosition = True;
if (firstProgramXID == 0)
InitChessProgram(appData.firstHost, appData.firstChessProgram,
&firstProgramPID, &toFirstProgFP,
&fromFirstProgFP, &firstProgramXID);
/*
* skip header information in position file
*/
fgets(line, MSG_SIZ, fp);
line[strlen(line) - 1] = '\0';
DisplayName(line);
fgets(line, MSG_SIZ, fp);
fgets(line, MSG_SIZ, fp);
for (i = BOARD_SIZE - 1; i >= 0; i--) {
fgets(line, MSG_SIZ, fp);
for (p = line, j = 0; j < BOARD_SIZE; p++) {
int promoted;
if (*p == '+')
{
promoted = True;
}
if (*p == ' ')
{
promoted = False;
}
p++;
initial_position[i][j++] = CharToPiece(*p,promoted);
}
}
{ int color;
for ( color = 0; color <= 1; color++ ) {
fscanf(fp, "%i%i%i%i%i%i%i%i\n",
&initial_catches[color][pawn],
&initial_catches[color][lance],
&initial_catches[color][knight],
&initial_catches[color][silver],
&initial_catches[color][gold],
&initial_catches[color][bishop],
&initial_catches[color][rook],
&initial_catches[color][king]);
};
}
whitePlaysFirst = False;
if (!feof(fp)) {
fgets(line, MSG_SIZ, fp);
if (strncmp(line, "white", strlen("white"))==0)
whitePlaysFirst = True;
}
fclose(fp);
if (whitePlaysFirst) {
CopyBoard(boards[0], initial_position);
CopyCatches(catches[0], initial_catches);
strcpy(moveList[0], " ...\n");
strcpy(parseList[0], " ...\n");
currentMove = forwardMostMove = 1;
CopyBoard(boards[1], initial_position);
CopyCatches(catches[1], initial_catches);
SendToProgram("force\n", toFirstProgFP);
SendCurrentBoard(toFirstProgFP);
DisplayMessage("White to play");
} else {
currentMove = forwardMostMove = 0;
CopyBoard(boards[0], initial_position);
CopyCatches(catches[0], initial_catches);
SendCurrentBoard(toFirstProgFP);
SendToProgram("force\n", toFirstProgFP);
DisplayMessage("Black to play");
}
DisplayClocks(ResetTimers);
DrawPosition(boardWidget, (XExposeEvent *) NULL);
return (int) True;
}
void
EditPositionProc()
{
if (gameMode == EditPosition) return;
ForceProc();
if (gameMode != ForceMoves) return;
DisplayName("<-- Press to set side to play next");
DisplayMessage("Mouse: 1=drag, 2=black, 3=white");
lastGameMode = gameMode = EditPosition;
ModeHighlight();
if (currentMove > 0)
CopyBoard(boards[0], boards[currentMove]);
whitePlaysFirst = !BLACK_ON_MOVE;
currentMove = forwardMostMove = 0;
}
void
EditPositionDone()
{
startedFromSetupPosition = True;
SendToProgram(appData.initString, toFirstProgFP);
SendSearchDepth(toFirstProgFP);
if (whitePlaysFirst) {
strcpy(moveList[0], " ...\n");
strcpy(parseList[0], " ...\n");
currentMove = forwardMostMove = 1;
CopyBoard(boards[1], boards[0]);
CopyCatches(catches[1], catches[0]);
SendToProgram("force\n", toFirstProgFP);
SendCurrentBoard(toFirstProgFP);
DisplayName(" ");
DisplayMessage("White to play");
} else {
currentMove = forwardMostMove = 0;
SendCurrentBoard(toFirstProgFP);
SendToProgram("force\n", toFirstProgFP);
DisplayName(" ");
DisplayMessage("Black to play");
}
lastGameMode = gameMode = SetupPosition;
}
void
MachinePlaysBlackProc()
{
if (gameMode == EditPosition) EditPositionDone();
if ((gameMode == EndOfGame) || (gameMode == PlayFromGameFile)
|| (gameMode == TwoMachinesPlay) || appData.noChessProgram
|| (gameMode == MachinePlaysBlack))
return;
if (!BLACK_ON_MOVE) {
DisplayMessage("It is not Black's turn");
return;
}
lastGameMode = gameMode = MachinePlaysBlack;
ModeHighlight();
SendToProgram(appData.blackString, toFirstProgFP);
DisplayClocks(StartTimers);
}
void
BackwardProc()
{
int i, j;
char buf[MSG_SIZ];
if ((currentMove <= 0) || (gameMode == TwoMachinesPlay)
|| (matchMode != MatchFalse) || (gameMode == EditPosition))
return;
if ((currentMove == 1) && whitePlaysFirst) return;
if (gameMode == EndOfGame) ResurrectChessProgram();
if ((BLACK_ON_MOVE && gameMode == MachinePlaysBlack)
|| (!BLACK_ON_MOVE && gameMode == MachinePlaysWhite)) {
DisplayMessage("Wait until your turn");
return;
}
Attention(firstProgramPID);
SendToProgram("undo\n", toFirstProgFP);
currentMove--;
if ((gameMode != ForceMoves) && (gameMode != PlayFromGameFile) &&
(gameMode != SetupPosition)) {
SendToProgram("force\n", toFirstProgFP);
lastGameMode = gameMode = ForceMoves;
ModeHighlight();
DisplayClocks(StopTimers);
}
DisplayClocks(ReDisplayTimers);
if (gameMode != PauseGame && gameMode != ForceMoves) {
PauseProc();
if (readGameXID != 0) {
XtRemoveTimeOut(readGameXID);
readGameXID = 0;
}
}
if (currentMove > 0) {
sprintf(buf, "%d. %s%s", (currentMove + 1) / 2,
BLACK_ON_MOVE ? "... " : "",
parseList[currentMove - 1]);
DisplayMessage(buf);
} else {
DisplayMessage("");
}
for (i = 0; i < BOARD_SIZE; i++)
for (j = 0; j < BOARD_SIZE; j++)
if (boards[currentMove][i][j] !=
boards[currentMove + 1][i][j]) {
DrawSquare(i, j, boards[currentMove][i][j]);
}
UpdateCatched(0,0,False,True,currentMove);
UpdateCatched(1,0,False,True,currentMove);
}
void
FlipProc()
{
flipView = !flipView;
DrawPosition(boardWidget, (XExposeEvent *) NULL);
}
void
SaveGameProc(name)
char *name;
{
char buf[MSG_SIZ], black_move[MSG_SIZ], white_move[MSG_SIZ];
int i, len, move = 0;
time_t tm;
if ( !filemodeUp ) {
strcpy(fmi.mode,"w");
if ((gameFileFP = fopen(name, "r")) != NULL) {
fclose(gameFileFP);
FileModePopUp(name);
return;
}
}
if ((gameFileFP = fopen(name, fmi.mode)) == NULL) {
sprintf(buf, "Can't open %s (mode %s)", name, fmi.mode);
DisplayMessage(buf);
return;
}
tm = time((time_t *) NULL);
gethostname(buf, MSG_SIZ);
#ifdef FULL_SAVE_GAME
fprintf(gameFileFP, "# %s game file -- %s", programName, ctime(&tm));
switch (lastGameMode) {
case MachinePlaysBlack:
fprintf(gameFileFP, "\t%s@%s vs. %s@%s\n",
appData.firstChessProgram, appData.firstHost,
getpwuid(getuid())->pw_name, buf);
break;
case MachinePlaysWhite:
fprintf(gameFileFP, "\t%s@%s vs. %s@%s\n",
getpwuid(getuid())->pw_name, buf,
appData.firstChessProgram, appData.firstHost);
break;
case TwoMachinesPlay:
fprintf(gameFileFP, "\t%s@%s vs. %s@%s\n",
appData.secondChessProgram, appData.secondHost,
appData.firstChessProgram, appData.firstHost);
break;
default:
fprintf(gameFileFP, "\n");
break;
}
fprintf(gameFileFP, "\talgebraic\n");
for (i = 0; i < currentMove;) {
fprintf(gameFileFP, "%d. %s ", ++move, parseList[i++]);
if (i >= currentMove) {
fprintf(gameFileFP, "\n");
break;
}
if ((len = strlen(parseList[i])) == 0) {
fprintf(gameFileFP, "\n");
break;
}
fprintf(gameFileFP, "%s\n", parseList[i++]);
}
#else
fprintf(gameFileFP, "#");
for (i = 0; i < currentMove;) {
if ( i % 5 == 0 )
fprintf(gameFileFP, "\n");
fprintf(gameFileFP, "%d. %s ", ++move, parseList[i++]);
if (i >= currentMove) {
fprintf(gameFileFP, "\n");
break;
}
if ((len = strlen(parseList[i])) == 0) {
break;
}
fprintf(gameFileFP, "%s ", parseList[i++]);
}
fprintf(gameFileFP, "\n");
#endif
fclose(gameFileFP);
gameFileFP = NULL;
}
#ifdef notdef
/* unused */
void
SwitchProc()
{
if (appData.noChessProgram) return;
switch (gameMode) {
default:
return;
case MachinePlaysBlack:
if (BLACK_ON_MOVE) {
DisplayMessage("Wait until your turn");
return;
}
lastGameMode = gameMode = MachinePlaysWhite;
ModeHighlight();
break;
case BeginningOfGame:
case MachinePlaysWhite:
if (!BLACK_ON_MOVE) {
DisplayMessage("Wait until your turn");
return;
}
if (currentMove == 0) {
MachinePlaysBlackProc();
return;
}
lastGameMode = gameMode = MachinePlaysBlack;
ModeHighlight();
break;
}
Attention(firstProgramPID);
SendToProgram("switch\n", toFirstProgFP);
}
#endif /*notdef*/
void
ForceProc()
{
switch (gameMode) {
case MachinePlaysBlack:
if (BLACK_ON_MOVE) {
DisplayMessage("Wait until your turn");
return;
}
Attention(firstProgramPID);
SendToProgram("force\n", toFirstProgFP);
break;
case MachinePlaysWhite:
if (!BLACK_ON_MOVE) {
DisplayMessage("Wait until your turn");
return;
}
Attention(firstProgramPID);
SendToProgram("force\n", toFirstProgFP);
break;
case BeginningOfGame:
SendToProgram("force\n", toFirstProgFP);
break;
case PlayFromGameFile:
if (readGameXID != 0) {
XtRemoveTimeOut(readGameXID);
readGameXID = 0;
}
if (gameFileFP != NULL) {
fclose(gameFileFP);
gameFileFP = NULL;
}
break;
case EndOfGame:
ResurrectChessProgram();
break;
case EditPosition:
EditPositionDone();
break;
case SetupPosition:
break;
default:
return;
}
lastGameMode = gameMode = ForceMoves;
ModeHighlight();
DisplayClocks(StopTimers);
}
void
HintProc()
{
if (appData.noChessProgram) return;
switch (gameMode) {
case MachinePlaysBlack:
if (BLACK_ON_MOVE) {
DisplayMessage("Wait until your turn");
return;
}
break;
case BeginningOfGame:
case MachinePlaysWhite:
if (!BLACK_ON_MOVE) {
DisplayMessage("Wait until your turn");
return;
}
break;
default:
DisplayMessage("No hint available");
return;
}
Attention(firstProgramPID);
SendToProgram("hint\n", toFirstProgFP);
}
void
SavePositionProc(name)
char *name;
{
char buf[MSG_SIZ], host_name[MSG_SIZ];
FILE *fp;
time_t tm;
int i, j;
if ((fp = fopen(name, "w")) == NULL) {
sprintf(buf, "Can't open %s", name);
DisplayMessage(buf);
return;
}
tm = time((time_t *) NULL);
gethostname(host_name, MSG_SIZ);
fprintf(fp, "%s position file -- %s", programName, ctime(&tm));
switch (lastGameMode) {
case MachinePlaysBlack:
fprintf(fp, "\t%s@%s vs. %s@%s\n", appData.firstChessProgram,
appData.firstHost, getpwuid(getuid())->pw_name,
host_name);
break;
case MachinePlaysWhite:
fprintf(fp, "\t%s@%s vs. %s@%s\n", getpwuid(getuid())->pw_name,
host_name, appData.firstChessProgram,
appData.firstHost);
break;
case TwoMachinesPlay:
fprintf(fp, "\t%s@%s vs. %s@%s\n", appData.secondChessProgram,
appData.secondHost, appData.firstChessProgram,
appData.firstHost);
break;
default:
fprintf(fp, "\n");
break;
}
fprintf(fp, "\n");
for (i = BOARD_SIZE - 1; i >= 0; i--) {
for (j = 0; j < BOARD_SIZE; j++) {
if ( pieceIsPromoted[(int) boards[currentMove][i][j]] )
fprintf(fp,"%c",'+');
else
fprintf(fp,"%c",' ');
fprintf(fp, "%c",
pieceToChar[(int) boards[currentMove][i][j]]);
if (j == BOARD_SIZE - 1)
fputc('\n', fp);
}
}
{ int color;
for (color = 0; color <= 1; color++)
{
fprintf(fp,"%i %i %i %i %i %i %i %i\n",
catches[currentMove][color][pawn],
catches[currentMove][color][lance],
catches[currentMove][color][knight],
catches[currentMove][color][silver],
catches[currentMove][color][gold],
catches[currentMove][color][bishop],
catches[currentMove][color][rook],
catches[currentMove][color][king]);
};
}
if ((gameMode == EditPosition) ? !whitePlaysFirst : BLACK_ON_MOVE)
fprintf(fp, "black to play\n");
else
fprintf(fp, "white to play\n");
fclose(fp);
}
void
TwoMachinesPlayProc()
{
int i;
MatchMode matchKind;
if ((gameMode == EndOfGame) || (gameMode == TwoMachinesPlay)
|| appData.noChessProgram)
return;
if (matchMode == MatchFalse) {
switch (gameMode) {
case PauseGame:
case PlayFromGameFile:
return;
case MachinePlaysBlack:
case MachinePlaysWhite:
ForceProc();
if (gameMode != ForceMoves) return;
matchKind = MatchOpening;
break;
case ForceMoves:
matchKind = MatchOpening;
break;
case SetupPosition:
matchKind = MatchPosition;
break;
case EditPosition:
EditPositionDone();
matchKind = MatchPosition;
break;
case BeginningOfGame:
default:
matchKind = MatchInit;
break;
}
} else {
matchKind = matchMode;
}
flipView = False;
firstMove = False;
DisplayClocks(ResetTimers);
DisplayClocks(StartTimers);
switch (matchKind) {
case MatchOpening:
if (firstProgramXID == 0) {
if (appData.loadGameFile == NULL) {
DisplayMessage("Select game file first");
return;
}
InitChessProgram(appData.firstHost,
appData.firstChessProgram,
&firstProgramPID, &toFirstProgFP,
&fromFirstProgFP, &firstProgramXID);
if (!PlayFromGameFileProc(appData.loadGameFile)) {
ShutdownChessPrograms("Bad game file");
return;
}
DrawPosition(boardWidget, (XExposeEvent *) NULL);
}
InitChessProgram(appData.secondHost,
appData.secondChessProgram,
&secondProgramPID, &toSecondProgFP,
&fromSecondProgFP, &secondProgramXID);
if (startedFromSetupPosition) {
if (whitePlaysFirst) {
i = 1;
SendToProgram("force\n", toSecondProgFP);
SendBoard(toSecondProgFP, boards[i], catches[i]);
} else {
i = 0;
SendBoard(toSecondProgFP, boards[i], catches[i]);
SendToProgram("force\n", toSecondProgFP);
}
} else {
i = 0;
SendToProgram("force\n", toSecondProgFP);
}
for (; i < currentMove; i++)
SendToProgram(moveList[i], toSecondProgFP);
lastGameMode = gameMode = TwoMachinesPlay;
ModeHighlight();
firstMove = True;
if (BLACK_ON_MOVE)
SendToProgram(appData.blackString, toSecondProgFP);
else
SendToProgram(appData.whiteString, toFirstProgFP);
break;
case MatchPosition:
if (firstProgramXID == 0) {
if (appData.loadPositionFile == NULL) {
DisplayMessage("Select position file first");
return;
}
InitChessProgram(appData.firstHost,
appData.firstChessProgram,
&firstProgramPID, &toFirstProgFP,
&fromFirstProgFP, &firstProgramXID);
if (!SetupPositionFromFileProc(
appData.loadPositionFile))
return;
}
InitChessProgram(appData.secondHost,
appData.secondChessProgram,
&secondProgramPID, &toSecondProgFP,
&fromSecondProgFP, &secondProgramXID);
if (whitePlaysFirst)
SendToProgram("force\n", toSecondProgFP);
SendCurrentBoard(toSecondProgFP);
lastGameMode = gameMode = TwoMachinesPlay;
ModeHighlight();
firstMove = True;
if (BLACK_ON_MOVE)
SendToProgram(appData.blackString, toSecondProgFP);
else
SendToProgram(appData.whiteString, toFirstProgFP);
break;
case MatchInit:
InitPosition();
if (firstProgramXID == 0)
InitChessProgram(appData.firstHost,
appData.firstChessProgram,
&firstProgramPID, &toFirstProgFP,
&fromFirstProgFP, &firstProgramXID);
InitChessProgram(appData.secondHost,
appData.secondChessProgram,
&secondProgramPID, &toSecondProgFP,
&fromSecondProgFP, &secondProgramXID);
lastGameMode = gameMode = TwoMachinesPlay;
ModeHighlight();
SendToProgram(appData.blackString, toSecondProgFP);
default:
break;
}
}
void
PauseProc()
{
static GameMode previous_mode = PauseGame;
switch (gameMode) {
case ForceMoves:
case EndOfGame:
case SetupPosition:
case EditPosition:
default:
return;
case PauseGame:
gameMode = previous_mode;
ModeHighlight();
previous_mode = PauseGame;
DisplayClocks(StartTimers);
DisplayMessage("");
break;
case PlayFromGameFile:
if (readGameXID == 0) {
readGameXID =
XtAppAddTimeOut(appContext,
(int) (1000 * appData.timeDelay),
(XtTimerCallbackProc) ReadGameFile, NULL);
} else {
XtRemoveTimeOut(readGameXID);
readGameXID = 0;
}
DisplayMessage("Pausing");
break;
case BeginningOfGame:
case MachinePlaysBlack:
case MachinePlaysWhite:
case TwoMachinesPlay:
if (currentMove == 0) /* don't pause if no one has moved */
return;
previous_mode = gameMode;
gameMode = PauseGame;
ModeHighlight();
DisplayClocks(StopTimers);
DisplayMessage("Pausing");
break;
}
}
void
GameProc()
{
if (gameMode != BeginningOfGame) {
DisplayMessage("Press Reset first");
return;
}
if (appData.loadGameFile == NULL)
FileNamePopUp("Game file name?",
VOID_PROC PlayFromGameFileProc);
else
(void) PlayFromGameFileProc(appData.loadGameFile);
}
void
Iconify()
{
Arg args[1];
fromX = fromY = -1;
XtSetArg(args[0], XtNiconic, True);
XtSetValues(shellWidget, args, 1);
}
void
SendToProgram(message, fp)
char *message;
FILE *fp;
{
if (fp == NULL) return;
lastMsgFP = fp;
if (xshogiDebug)
fprintf(stderr, "Sending to %s: %s\n",
fp == toFirstProgFP ? "first" : "second", message);
if (message[strlen(message) - 1] != '\n')
fprintf(fp, "\n%s\n", message);
else
fputs(message, fp);
fflush(fp);
}
void
ReceiveFromProgram(fp, source, id)
FILE *fp;
int *source;
XtInputId *id;
{
char message[MSG_SIZ], *end_str;
if (fgets(message, MSG_SIZ, fp) == NULL) {
sprintf(message,
"%s chess program (%s) exited unexpectedly",
fp == fromFirstProgFP ? "first" : "second",
fp == fromFirstProgFP ? appData.firstChessProgram
: appData.secondChessProgram);
fprintf(stderr, "%s: %s\n", programName, message);
ShutdownChessPrograms(message);
return;
}
if ((end_str = (char *) strchr(message, '\r')) != NULL)
*end_str = '\0';
if ((end_str = (char *) strchr(message, '\n')) != NULL)
*end_str = '\0';
if (xshogiDebug)
fprintf(stderr, "Received from %s: %s\n",
fp == fromFirstProgFP ? "first" : "second", message);
HandleMachineMove(message, fp);
}
void
SendSearchDepth(fp)
FILE *fp;
{
char message[MSG_SIZ];
if (appData.searchDepth <= 0) return;
sprintf(message, "depth\n%d\nhelp\n", appData.searchDepth);
/* note kludge: "help" command forces gnuchessx to print
out something that ends with a newline. */
SendToProgram(message, fp);
}
void
DisplayMessage(message)
char *message;
{
Arg arg;
XtSetArg(arg, XtNlabel, message);
XtSetValues(messageWidget, &arg, 1);
}
void
DisplayName(name)
char *name;
{
Arg arg;
XtSetArg(arg, XtNlabel, name);
XtSetValues(nameWidget, &arg, 1);
}
/*
* This routine sends a SIGINT (^C interrupt) to gnuchess to awaken it
* if it might be busy thinking on our time. This normally isn't needed,
* but is useful on systems where the FIONREAD ioctl doesn't work (such
* as ESIX), since on those systems the gnuchess feature that lets you
* interrupt its thinking just by typing a command does not work.
*
* In the future, similar code could be used to stop gnuchess and make
* it move immediately when it is thinking about its own move; this could
* be useful if we want to make Backward or ForceMoves work while gnuchess
* is thinking. --t.mann
*/
void
Attention(pid)
int pid;
{
#if defined(ATTENTION) || defined(ESIX) || !defined(FIONREAD)
if (appData.noChessProgram || (pid == 0)) return;
switch (gameMode) {
case MachinePlaysBlack:
case MachinePlaysWhite:
case TwoMachinesPlay:
if (currentMove > (whitePlaysFirst ? 2 : 1) && maybeThinking) {
if (xshogiDebug)
fprintf(stderr, "Sending SIGINT to %s\n",
pid == firstProgramPID ? "first" : "second");
(void) kill(pid, SIGINT); /* stop it thinking */
}
break;
}
#endif /*ATTENTION*/
}
void
CheckFlags()
{
if (blackTimeRemaining <= 0) {
blackTimeRemaining = 0;
if (!blackFlag) {
blackFlag = True;
if (whiteFlag)
DisplayName(" Both flags have fallen");
else
DisplayName(" Black's flag has fallen");
}
}
if (whiteTimeRemaining <= 0) {
whiteTimeRemaining = 0;
if (!whiteFlag) {
whiteFlag = True;
if (blackFlag)
DisplayName(" Both flags have fallen");
else
DisplayName(" White's flag has fallen");
}
}
}
void
CheckTimeControl()
{
if (!appData.clockMode) return;
if (currentMove == 0) return;
/*
* add time to clocks when time control is achieved
*/
if ((currentMove % (appData.movesPerSession * 2)) == 0) {
if (blackTimeRemaining > 0)
blackTimeRemaining += timeControl;
if (whiteTimeRemaining > 0)
whiteTimeRemaining += timeControl;
}
}
void
DisplayLabels()
{
DisplayTimerLabel(blackTimerWidget, "Black",
blackTimeRemaining);
DisplayTimerLabel(whiteTimerWidget, "White",
whiteTimeRemaining);
}
#ifdef HAS_GETTIMEOFDAY
static struct timeval tickStartTV;
static int tickLength;
int
PartialTickLength()
{
struct timeval tv;
struct timezone tz;
int ptl;
gettimeofday(&tv, &tz);
ptl = ( (tv.tv_sec - tickStartTV.tv_sec)*1000000 +
(tv.tv_usec - tickStartTV.tv_usec) + 500 ) / 1000;
if (ptl > tickLength) ptl = tickLength;
return ptl;
}
#else /*!HAS_GETTIMEOFDAY*/
#define tickLength 1000
#endif /*HAS_GETTIMEOFDAY*/
/*
* DisplayClocks manages the game clocks.
*
* In tournament play, white starts the clock and then black makes a move.
* We give the human user a slight advantage if he is playing black---the
* clocks don't run until he makes his first move, so it takes zero time.
* Also, DisplayClocks doesn't account for network lag so it could get
* out of sync with GNU Shogi's clock -- but then, referees are always right.
*/
void
DisplayClocks(clock_mode)
int clock_mode;
{
#ifdef HAS_GETTIMEOFDAY
struct timezone tz;
#endif /*HAS_GETTIMEOFDAY*/
long timeRemaining;
switch (clock_mode) {
case ResetTimers:
/* Stop clocks and reset to a fresh time control */
if (timerXID != 0) {
XtRemoveTimeOut(timerXID);
timerXID = 0;
}
blackTimeRemaining = timeControl;
whiteTimeRemaining = timeControl;
if (blackFlag || whiteFlag) {
DisplayName("");
blackFlag = whiteFlag = False;
}
DisplayLabels();
break;
case DecrementTimers:
/* Decrement running clock to next 1-second boundary */
if (gameMode == PauseGame) return;
if (!appData.clockMode) return;
if (BLACK_ON_MOVE)
timeRemaining = blackTimeRemaining -= tickLength;
else
timeRemaining = whiteTimeRemaining -= tickLength;
CheckFlags();
DisplayLabels();
if (timeRemaining == 0) return;
#ifdef HAS_GETTIMEOFDAY
tickLength = (timeRemaining <= 1000) ? 100 : 1000;
gettimeofday(&tickStartTV, &tz);
#endif /*HAS_GETTIMEOFDAY*/
timerXID =
XtAppAddTimeOut(appContext, tickLength,
(XtTimerCallbackProc) DisplayClocks,
(XtPointer) DecrementTimers);
break;
case SwitchTimers:
/* A player has just moved, so stop the previously running
clock and start the other one. */
if (timerXID != 0) {
XtRemoveTimeOut(timerXID);
timerXID = 0;
#ifdef HAS_GETTIMEOFDAY
if (appData.clockMode) {
if (BLACK_ON_MOVE)
whiteTimeRemaining -= PartialTickLength();
else
blackTimeRemaining -= PartialTickLength();
CheckFlags();
}
#endif /*HAS_GETTIMEOFDAY*/
}
CheckTimeControl();
DisplayLabels();
if (!appData.clockMode) return;
timeRemaining = BLACK_ON_MOVE ?
blackTimeRemaining : whiteTimeRemaining;
if (timeRemaining == 0) return;
#ifdef HAS_GETTIMEOFDAY
tickLength = (timeRemaining <= 1000) ?
((timeRemaining-1) % 100) + 1 :
((timeRemaining-1) % 1000) + 1;
gettimeofday(&tickStartTV, &tz);
#endif /*HAS_GETTIMEOFDAY*/
timerXID =
XtAppAddTimeOut(appContext, tickLength,
(XtTimerCallbackProc) DisplayClocks,
(XtPointer) DecrementTimers);
break;
case ReDisplayTimers:
/* Display current clock values */
DisplayLabels();
break;
case StopTimers:
/* Stop both clocks */
if (timerXID == 0)
return;
XtRemoveTimeOut(timerXID);
timerXID = 0;
if (!appData.clockMode) return;
#ifdef HAS_GETTIMEOFDAY
if (BLACK_ON_MOVE)
whiteTimeRemaining -= PartialTickLength();
else
blackTimeRemaining -= PartialTickLength();
CheckFlags();
DisplayLabels();
#endif /*HAS_GETTIMEOFDAY*/
break;
case StartTimers:
/* Start clock of player on move, if not already running. */
if (timerXID != 0)
return;
DisplayLabels();
if (!appData.clockMode) return;
timeRemaining = BLACK_ON_MOVE ?
blackTimeRemaining : whiteTimeRemaining;
if (timeRemaining == 0) return;
#ifdef HAS_GETTIMEOFDAY
tickLength = (timeRemaining <= 1000) ?
((timeRemaining-1) % 100) + 1 :
((timeRemaining-1) % 1000) + 1;
gettimeofday(&tickStartTV, &tz);
#endif /*HAS_GETTIMEOFDAY*/
timerXID =
XtAppAddTimeOut(appContext, tickLength,
(XtTimerCallbackProc) DisplayClocks,
(XtPointer)DecrementTimers);
break;
}
}
void
DisplayTimerLabel(w, color, timer)
Widget w;
char *color;
long timer;
{
char buf[MSG_SIZ];
Arg args[3];
if (appData.clockMode) {
sprintf(buf, "%s: %s", color, TimeString(timer));
XtSetArg(args[0], XtNlabel, buf);
} else
XtSetArg(args[0], XtNlabel, color);
if (((color[0] == 'W') && BLACK_ON_MOVE)
|| ((color[0] == 'B') && !BLACK_ON_MOVE)) {
XtSetArg(args[1], XtNbackground, timerForegroundPixel);
XtSetArg(args[2], XtNforeground, timerBackgroundPixel);
} else {
XtSetArg(args[1], XtNbackground, timerBackgroundPixel);
XtSetArg(args[2], XtNforeground, timerForegroundPixel);
}
XtSetValues(w, args, 3);
}
char *
TimeString(tm)
long tm;
{
int second, minute, hour, day;
static char buf[32];
if (tm > 0 && tm <= 900) {
/* convert milliseconds to tenths, rounding up */
sprintf(buf, " 0.%1d ", (tm+99)/100);
return buf;
}
/* convert milliseconds to seconds, rounding up */
tm = (tm + 999) / 1000;
if (tm >= (60 * 60 * 24)) {
day = (int) (tm / (60 * 60 * 24));
tm -= day * 60 * 60 * 24;
} else
day = 0;
if (tm >= (60 * 60)) {
hour = (int) (tm / (60 * 60));
tm -= hour * 60 * 60;
} else
hour = 0;
if (tm >= 60) {
minute = (int) (tm / 60);
tm -= minute * 60;
} else
minute = 0;
second = tm % 60;
if (day > 0)
sprintf(buf, " %d:%02d:%02d:%02d ", day, hour, minute, second);
else if (hour > 0)
sprintf(buf, " %d:%02d:%02d ", hour, minute, second);
else
sprintf(buf, " %2d:%02d ", minute, second);
return buf;
}
void
Usage()
{
fprintf(stderr, "Usage: %s\n", programName);
fprintf(stderr, "\tstandard Xt options\n");
fprintf(stderr, "\t-iconic\n");
fprintf(stderr, "\t-tc or -timeControl minutes[:seconds]\n");
fprintf(stderr, "\t-mps or -movesPerSession moves\n");
fprintf(stderr, "\t-st or -searchTime minutes[:seconds]\n");
fprintf(stderr, "\t-sd or -searchDepth number\n");
fprintf(stderr, "\t-clock or -clockMode (True | False)\n");
fprintf(stderr, "\t-td or -timeDelay seconds\n");
fprintf(stderr, "\t-ncp or -noChessProgram (True | False)\n");
fprintf(stderr, "\t-fcp or -firstChessProgram program_name\n");
fprintf(stderr, "\t-scp or -secondChessProgram program_name\n");
fprintf(stderr, "\t-fh or -firstHost host_name\n");
fprintf(stderr, "\t-sh or -secondHost host_name\n");
fprintf(stderr, "\t-rsh or -remoteShell shell_name\n");
fprintf(stderr,
"\t-mm or -matchMode (False | Init | Position | Opening)\n");
fprintf(stderr, "\t-lgf or -loadGameFile file_name\n");
fprintf(stderr, "\t-lpf or -loadPositionFile file_name\n");
fprintf(stderr, "\t-sgf or -saveGameFile file_name\n");
fprintf(stderr, "\t-spf or -savePositionFile file_name\n");
fprintf(stderr, "\t-size or -boardSize (Large | Medium | Small)\n");
fprintf(stderr, "\t-coords or -showCoords (True | False)\n");
fprintf(stderr, "\t-mono or -monoMode (True | False)\n");
fprintf(stderr, "\t-wpc or -blackPieceColor color\n");
fprintf(stderr, "\t-bpc or -whitePieceColor color\n");
fprintf(stderr, "\t-lsc or -lightSquareColor color\n");
fprintf(stderr, "\t-dsc or -darkSquareColor color\n");
fprintf(stderr, "\t-debug or -debugMode (True | False)\n");
exit(2);
}
/*
* This is necessary because some C libraries aren't ANSI C compliant yet.
*/
char *
StrStr(string, match)
char *string, *match;
{
int i, length;
length = strlen(match);
for (i = strlen(string) - length; i >= 0; i--, string++)
if (!strncmp(match, string, (size_t) length))
return string;
return NULL;
}
int
StrCaseCmp(s1, s2)
char *s1, *s2;
{
char c1, c2;
for (;;) {
c1 = ToLower(*s1++);
c2 = ToLower(*s2++);
if (c1 > c2) return 1;
if (c1 < c2) return -1;
if (c1 == '\000') return 0;
}
}
int
ToLower(c)
int c;
{
return isupper(c) ? tolower(c) : c;
}
int
ToUpper(c)
int c;
{
return islower(c) ? toupper(c) : c;
}
#if SYSTEM_FIVE || SYSV
#ifdef IRIX /*??*/
char *
PseudoTTY(ptyv)
int *ptyv;
{
char *line;
line = (char *)_getpty(ptyv, O_RDWR, 0600, 0);
if (0 == line)
return NULL;
return line;
}
#else /*!IRIX*/
char *
PseudoTTY(ptyv)
int *ptyv;
{
#if SVR4
char *ptsname(), *ptss;
*ptyv = open("/dev/ptmx", O_RDWR);
if (*ptyv > 0 ) {
if (grantpt(*ptyv) == -1)
return NULL;
if (unlockpt(*ptyv) == -1)
return NULL;
if (!(ptss = ptsname(*ptyv)))
return NULL;
strncpy(ptyname, ptss, sizeof(ptyname));
ptyname[sizeof(ptyname) -1] = 0;
return ptyname;
}
#else /* !SVR4 */
struct stat stb;
int c, i;
for (c = 'p'; c <= 'z'; c++)
#if defined(HPUX) || defined(hpux)
for (i = 0; i < 15 /*??*/; i++) {
sprintf(ptyname, "/dev/ptym/pty%c%x", c, i);
#else /* !HPUX */
for (i = 0; i < 16; i++) {
#ifdef RTU
sprintf(ptyname, "/dev/pty%x", i);
#else /* !RTU */
sprintf(ptyname, "/dev/pty%c%x", c, i);
#endif /* RTU */
#endif /* HPUX */
#ifdef IRIS
*ptyv = open("/dev/ptc", O_RDWR, 0);
if (*ptyv < 0)
return NULL;
if (fstat(*ptyv, &stb) < 0)
return NULL;
#else /* !IRIS */
if (stat(ptyname, &stb) < 0)
return NULL;
*ptyv = open(ptyname, O_RDWR, 0);
#endif /* IRIS */
if (*ptyv >= 0) {
#if defined(HPUX) || defined(hpux)
sprintf(ptyname, "/dev/pty/tty%c%x", c, i);
#else /* !HPUX */
#ifdef RTU
sprintf(ptyname, "/dev/ttyp%x", i);
#else /* !RTU */
#ifdef IRIS
sprintf(ptyname, "/dev/ttyq%d",
minor(stb.st_rdev));
#else /* !IRIS, !RTU, !HPUX */
sprintf(ptyname, "/dev/tty%c%x", c, i);
#endif /* IRIS */
#endif /* RTU */
#endif /* HPUX */
#ifndef UNIPLUS
if (access(ptyname, 6) != 0) {
close(*ptyv);
#ifdef IRIS
return NULL;
#else /* !IRIS */
continue;
#endif /* IRIS */
}
#endif /* !UNIPLUS */
#ifdef IBMRTAIX
signal(SIGHUP, SIG_IGN);
#endif /* IBMRTAIX */
return ptyname;
}
}
#endif
return NULL;
}
#endif /*IRIX*/
#else /* !SYSTEM_FIVE */
void
CatchPipeSignal(dummy)
int dummy;
{
char message[MSG_SIZ];
sprintf(message,
"%s chess program (%s) exited unexpectedly",
lastMsgFP == toFirstProgFP ? "first" : "second",
lastMsgFP == toFirstProgFP ? appData.firstChessProgram
: appData.secondChessProgram);
fprintf(stderr, "%s: %s\n", programName, message);
ShutdownChessPrograms(message);
return;
}
#endif